为什么在迭代时修改列表会导致跳过元素?
我现在正在用Python开发一个程序,最近发现语言中的foreach循环或者列表结构好像有点问题。为了简单起见,我就用一个通用的例子来说明我的问题,因为我在我的程序和这个例子中都遇到了同样的错误:
x = [1,2,2,2,2]
for i in x:
x.remove(i)
print x
问题很简单,我原以为这段代码是用来清空列表中所有元素的。但是执行后,我发现列表里总是剩下两个元素。
我哪里做错了呢?提前谢谢大家的帮助。
补充:我并不是想清空一个列表,这只是一个例子……
8 个回答
6
我觉得,简单来说,当你写:
for x in lst:
# loop body goes here
在背后,Python 大概是这样工作的:
i = 0
while i < len(lst):
x = lst[i]
# loop body goes here
i += 1
如果你把 lst.remove(x)
放在循环的主体里,也许你就能明白为什么会得到这样的结果?
其实,Python 是用一个移动的指针来遍历列表的。这个指针一开始指向第一个元素。然后你删除了第一个元素,这样第二个元素就成了新的第一个元素。接着,指针移动到新的第二个元素,也就是之前的第三个元素。然后继续这样下去。(如果你用 [1,2,3,4,5] 作为示例列表,可能会更清楚一些,而不是 [1,2,2,2,2])
10
当你删除一个元素时,循环会自动跳到下一个位置,这样就会漏掉一个元素。
可以试着从后往前删除。或者请说出你真正遇到的问题。
38
在Python中,有一个很明确的规则,就是在遍历一个列表的时候,不应该去修改这个列表。你可以试试下面的方法:
for i in x[:]:
x.remove(i)
这里的[:]
是用来获取x
的一个“切片”,这个切片包含了x
的所有元素,所以实际上就是x
的一个副本。