迭代并从列表中删除项目

时间:2016-01-29 15:37:14

标签: python-2.7

b = [1,2,3,4,5,6,7]
    for n in b:
        if n > 3:
            b.remove(n)

我打印b,并获得以下列表:

[1,2,3,5,7]

为什么5和7仍然存在?我可以创建一个几乎完全相同的功能并从列表中删除所有关于3的数字,那么为什么我不能在终端中做同样的事情呢?

3 个答案:

答案 0 :(得分:3)

这是一个众所周知的问题。在使用迭代器时修改底层集合时,迭代器不可靠。

至于你遇到的行为:

使用CPython,列表迭代器由数组的索引表示。如果在迭代器位置或之前从列表中删除项目,同时仍在迭代它,则迭代器会向前跳转。迭代器位置索引仍然相同,但所有项目"在#34;迭代器刚刚向左移动了一个位置。这使得迭代器跳过一个元素。因此,您只删除每一个项目。

l = [1, 2, 3, 4]
        ^it(pos=1)

l.remove(2)
l = [1, 3, 4]
        ^it(pos=1)

it.next()     # automatically at the end of each for loop 
l = [1, 3, 4] # we just skipped over an item
           ^it(pos=2)
关于@mgiuca主题的

Here's a nice little treatise

有趣的是,在迭代器位置之后删除项目对于当前的实现来说是安全的。

简而言之:在迭代它们时不要修改集合。列表的替代方案:Remove items from a list while iterating in Python

答案 1 :(得分:1)

那是因为你在同一个列表上进行迭代。试试这个:

b = [1,2,3,4,5,6,7]
c = b[:]
for n in c:
    if n > 3:
        b.remove(n)

如果您看到下面的图片,现在我创建了两个不同的列表。

enter image description here

答案 2 :(得分:0)

删除元素时,数组会被修改(元素向左移动),因此下一次迭代会将您带到绕过移位元素的下一个元素。也就是说,数组被修改,循环前进到下一个索引。这就是为什么每次删除元素时都会注意到跳转的原因。