python:迭代弹出元素时出现列表索引超出范围错误
我写了一个简单的Python程序
l=[1,2,3,0,0,1]
for i in range(0,len(l)):
if l[i]==0:
l.pop(i)
在这一行if l[i]==0:
上,我遇到了“列表索引超出范围”的错误。
经过调试,我发现i
的值在增加,而列表的长度在减少。
不过,我设置了循环的结束条件是i < len(l)
。那为什么还会出现这个错误呢?
12 个回答
6
你在遍历列表的时候改变了它的大小,这可能不是你想要的,这也是你出错的原因。
补充:正如其他人所说和评论的那样,列表推导式通常是更好的选择,尤其是在回答这个问题时。我提供这个作为一个替代方案,虽然不是最好的答案,但它仍然能解决问题。
所以,顺便提一下,你也可以使用 filter
,它允许你调用一个函数来筛选出你不想要的列表项。
举个例子:
>>> l = [1,2,3,0,0,1]
>>> filter(lambda x: x > 0, l)
[1, 2, 3]
活到老,学到老。简单的东西更好,除非你需要复杂的东西。
19
表达式 len(l)
只会在 range()
函数被计算的时候执行一次。那时候创建的范围对象是固定的,它不会改变;它根本不知道 l
这个对象的任何信息。
顺便说一下,l
这个名字不太好!它看起来像数字1,或者大写字母I。
67
你在遍历列表 l
的时候,正在减少它的长度,所以当你接近范围语句中的索引末尾时,有些索引就不再有效了。
看起来你想做的是:
l = [x for x in l if x != 0]
这个操作会返回一个新的列表,里面没有任何值为零的元素(这个操作叫做 列表推导,顺便提一下)。你甚至可以把最后那部分简化成 if x
,因为非零数字会被认为是 True
。
在你写的代码中,并没有 i < len(l)
这样的循环结束条件,因为 len(l)
是在循环开始前就计算好的,而不是在每次循环时重新计算。不过,你可以这样写:
i = 0
while i < len(l):
if l[i] == 0:
l.pop(i)
else:
i += 1