Python代码报错:r[-1]被识别为int而非list,求原因及解决
问题描述
这是一道编程练习题,要求定义一个函数,接收由1-9数字组成的字符串,输出符合以下规则的列表:
- 字符串中的每个数字都要加入列表;
- 若字符串中的数字x小于等于最近的主列表元素y,则将x加入子列表;持续向该子列表添加后续数字,直到遇到大于y的数字z,再将z加入主列表,继续后续处理。
示例
string = '543987'; result = [5,[4,3],9,[8,7]]
string= '987654321'; result = [9,[8,7,6,5,4,3,2,1]]
string = '455532123266'; result = [4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]]
string = '123456789'; result = [1, 2, 3, 4, 5, 6, 7, 8, 9]
我的代码
def numbers_in_lists(s): n=len(s) p=[] i=0 while i<=n-1: p.append(int(s[i])) i=i+1 r=[p[0]] if p[1]<=p[0]: r.append([p[1]]) else: r.append(p[1]) if n<=2: return r j=2 while j<=n-1: if p[j]<=p[j-1]: if p[j-1]<=p[j-2]: r[-1].append(p[j]) else: r.append(p[j]) else: if p[j]<=p[j-2]: r[-1].append(p[j]) else: r.append(p[j]) j=j+1 return r
报错信息
运行
print(numbers_in_lists('543987'))时出现报错:
Traceback (most recent call last):
File "Lesson14Quiz3.py", line 33, in
print (numbers_in_lists(string))
File "Lesson14Quiz3.py", line 20, in numbers_in_lists
r[-1].append(p[j])
AttributeError: 'int' object has no attribute 'append'
我的疑问
问题出在r[-1].append(p[j])这一行,我认为满足前置条件时r[-1]应该是列表而非整数,求解答。
问题根源分析
咱们拿你的测试用例'543987'走一遍代码流程,就能清楚看到问题所在:
- 首先把字符串转成整数列表
p = [5,4,3,9,8,7] - 初始化
r = [5],因为4<=5,所以r变成[5, [4]] - 当
j=2(对应数字3):3 <= 4,进入第一个if分支- 判断
4 <=5成立,于是往r[-1](也就是[4])里添加3,r变成[5, [4,3]],这一步没问题
- 当
j=3(对应数字9):9>3,进入else分支- 判断
9<=3不成立,所以把9直接加入r,此时r = [5, [4,3], 9]
- 当
j=4(对应数字8):8<=9,进入第一个if分支- 判断
9<=3?这显然是False!所以代码执行r.append(8),r变成[5, [4,3], 9, 8]——注意这里r[-1]已经是整数8了
- 当
j=5(对应数字7):7<=8,进入第一个if分支- 判断
8<=9成立,代码尝试执行r[-1].append(7),但r[-1]是整数8,自然就抛出AttributeError了!
你的核心问题是:用相邻两个数字的大小关系来判断是否应该往子列表里加元素,但这个关系和r的最后一个元素类型没有必然联系。比如上面的步骤5,虽然8<=9,但前一个数字9比前前个数字3大,你的代码就错误地把8当成了主列表元素,导致后续操作失败。
修复方案
解决这个问题的关键是跟踪最近的主列表元素,而不是依赖相邻数字的大小。我们需要维护一个变量记录当前最近的主列表元素,然后根据当前数字和这个元素的大小关系来决定如何分组:
def numbers_in_lists(s): # 把字符串快速转成整数列表,替代你原来的while循环 nums = [int(c) for c in s] if not nums: return [] result = [nums[0]] # 记录最近的主列表元素 last_main = nums[0] for x in nums[1:]: if x <= last_main: # 如果当前应该加入子列表: # 检查结果最后一个元素是不是列表,是就追加,不是就新建子列表 if isinstance(result[-1], list): result[-1].append(x) else: result.append([x]) else: # 当前数字大于最近主元素,加入主列表并更新最近主元素 result.append(x) last_main = x return result
测试验证
运行以下测试代码,完全符合示例要求:
print(numbers_in_lists('543987')) # 输出 [5, [4, 3], 9, [8, 7]] print(numbers_in_lists('987654321')) # 输出 [9, [8, 7, 6, 5, 4, 3, 2, 1]] print(numbers_in_lists('455532123266')) # 输出 [4, 5, [5, 5, 3, 2, 1, 2, 3, 2], 6, [6]] print(numbers_in_lists('123456789')) # 输出 [1, 2, 3, 4, 5, 6, 7, 8, 9]
总结
你的思路方向是对的,但错误地用相邻数字的大小关系代替了“当前数字与最近主元素的大小关系”这个核心判断条件。通过维护last_main变量,我们可以准确控制分组逻辑,同时检查结果列表的最后一个元素类型,避免出现调用整数append方法的错误。
内容的提问来源于stack exchange,提问作者failbetter

