我有四个数字列表:
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]
这里发生了什么?我错过了什么?
答案 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
索引仍然有效,就像您尚未评估的所有项目一样!