循环列表时出现意外行为

时间:2013-06-04 00:06:15

标签: python list for-loop modulo

我有四个数字列表:

mylist=[3,5,67,4]

我想删除所有奇数。所以,我写了以下内容:

for item in mylist:
  if item%2==1:
    mylist.remove(item)

当我打印mylist时,我得到以下内容:

[5,4]

我无法弄清楚为什么会这样。但是,当我在if语句后添加一个print语句时,我得到了正确的答案:

for item in mylist:
  if item%2==1:
    mylist.remove(item)
  print mylist

产生:

[4]

这里发生了什么?我错过了什么?

3 个答案:

答案 0 :(得分:5)

在迭代时就地修改列表是个坏主意。当您迭代它时列表会发生变化,您的迭代会继续进行,就好像列表没有改变一样 - 产生奇怪的结果。

最佳解决方案是建立一个新列表 - 最好使用list comprehension代替:

mylist = [item for item in mylist if item % 2 == 0]

如果您必须修改列表,您可以在之后重新分配值(mylist[:] = ...),但您不太可能需要来就地修改它。

这也具有可读性和简洁性的优点。

答案 1 :(得分:3)

您需要遍历列表的副本。直接在循环中修改列表是导致您遇到问题的原因。以下是首选方法:

for item in mylist[:]:
    if item%2==1:
        mylist.remove(item)

答案 2 :(得分:0)

我同意其他答案,这些答案表示迭代列表并在循环中修改该列表是不安全的。我发现这种问题的一个解决方案 - 特别是从列表中删除 - 是使用索引而不是迭代器来循环向后

我的python代码生锈了所以我将使用类似C的伪代码...

for ( i = lastindex; i >= 0; --i )
  if ( some condition involving list[i] )
    remove item at index i

从列表中删除时这是有效的,因为删除后移动的项目是您已经查看过的项目;您的i索引仍然有效,就像您尚未评估的所有项目一样!