Python 通过迭代从列表中删除特定项

Python 通过迭代从列表中删除特定项,python,list,loops,Python,List,Loops,我想通过迭代和检查python列表是否满足某些要求,从python列表中删除特定项。起初,我只是对自定义类对象列表进行操作,但实际上遇到了一些错误,我在一个基本类型为int的python列表上进行了实验,只是为了找到奇怪的结果 以下是一些代码摘录: >>> a=[1,2,3,4,5] >>> for i in a: ... a.remove(i) ... >>> a [2, 4] 我希望a在循环之后应该是[],但事实证明它是[2,

我想通过迭代和检查python列表是否满足某些要求,从python列表中删除特定项。起初,我只是对自定义类对象列表进行操作,但实际上遇到了一些错误,我在一个基本类型为int的python列表上进行了实验,只是为了找到奇怪的结果

以下是一些代码摘录:

>>> a=[1,2,3,4,5]
>>> for i in a:
...     a.remove(i)
... 
>>> a
[2, 4]

我希望
a
在循环之后应该是
[]
,但事实证明它是
[2,4]
,我不知道为什么。我在中发现了一个相关的问题,但它只给出了如何删除特定项的解决方案,实际上与机制无关。我真想知道这个奇怪结果的原因

让我们在迭代时尝试打印i和a的值

for i in a:
     print i, a
     a.remove(i)
输出将是:

1 [1, 2, 3, 4, 5]
3 [2, 3, 4, 5]
5 [2, 4, 5]

因此,当您删除一个元素时,索引将发生变化,因此,虽然索引1的值以前是2,但现在是3。这将是i的值。

解决方案不能按预期工作的原因是,如果修改列表,迭代器的行为与预期不符。如果你的例子是这样改写的,你会得到你期望的结果

>>> a=[1,2,3,4,5]
>>> b = a[:]
>>> for i in b:
...     a.remove(i)
... 
>>> a
[]
这是因为“b”是“a”的副本,所以当a修改时,be不会被修改。这意味着迭代器下面没有修改数据结构

更有效的解决方案是:

a = [1,2,3,4,5]
a = [i for i in a if not condition(i)]

此列表在遍历源列表时进行复制,只需复制未被删除的元素。

因此,您已经公开了一些python实现。基本上,数组增强了python列表的能力,它只是将数组索引增加1。所以它将转到
a[0]
a[1]
a[2]
。。。并在每次迭代之前检查它不会从数组的末尾运行。从列表中删除第一项“1”时,“2”将移动到
a[0]
。该数组现在看起来像
[2,3,4,5]
。迭代器现在指向
a[1]
,因此现在“3”被删除。最后,跳过“4”、“5”将被删除

a = [1,2,3,4,5]

for i in a:
  print("a:%s i=%s"%(a,i))
  a.remove(i)

print("final a: %s"%a)
给出输出

a:[1, 2, 3, 4, 5] i=1
a:[2, 3, 4, 5] i=3
a:[2, 4, 5] i=5
final a: [2, 4]
如果你感兴趣的话,这是真正的细节。

在迭代列表时,切勿从列表中删除项目。这将使您的迭代器无效。对于您引用的问题,此答案给出了原因的解释。请思考当您
时会发生什么。当
i
1
时,请删除(i)
,因此您处于
a[0]
。您的列表现在变成
[2,3,4,5]
。您的迭代器继续移动到位置
a[1]
,现在是值3…明白了!谢谢你的时间!