迭代列表时出现意外行为

时间:2015-02-24 21:46:08

标签: python python-2.7

我没想到这会起作用,因为我正在修改被迭代的对象,但我没想到它会以这种方式失败。我实际上预计会引发异常。

>>> x = [1, 2, 3]
>>> for a in x:
...   print a, x.pop(0)
... 
1 1
3 2
>>> x
    [3]

范围稍大:

>>> x = [1, 2, 3, 4]
>>> for a in x:
...   print a, x.pop(0)
... 
1 1
3 2
>>> x
    [3, 4]

还有点大一点:

>>> x = [1, 2, 3, 4, 5]
>>> for a in x:
...   print a, x.pop(0)
... 
1 1
3 2
5 3
>>> x
    [4, 5]

就像for循环是从列表中创建一个生成器,但比较"索引"到列表的长度来决定何时迭代结束。

看起来这仍然会产生异常,而不是这种奇怪的行为。是否有某种原因它没有引发异常?

1 个答案:

答案 0 :(得分:0)

正如您所知,for循环在内部使用索引,在每次迭代时将其递增1,并在索引超出列表长度时停止。这就是为列表定义迭代的方式。它以其他方式为其他类型定义,您可以通过实现__iter__为自己的类定义它。

在迭代时修改列表是合法的,并且一旦了解了它的工作原理就可以预测。删除一个或多个项目后,项目向下移动到较低的索引,如果删除的项目的索引小于或等于循环的当前索引,则在循环递增时最终跳过项目指数。

有许多解决方案:以相反顺序迭代,遍历副本,制作要删除的索引列表并单独执行,构建新列表而不是修改现有列表,使用{{1如果你有条件地删除项目,则循环而不是while语句......也可能有其他方法。