2

In my Python 2.7.2 IDLE interpreter:

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

>>> mylist
[2, 4]

Why?

4

6 回答 6

5

这是因为当您遍历列表时,python 会跟踪列表中的索引。请考虑以下代码:

for i in range(len(mylist)):
    if i >= len(mylist):
       break
    item = mylist[i]
    mylist.remove(item)

如果我们跟踪这一点(这实际上是 python 在您的代码中所做的事情),那么我们会看到,当我们删除列表中的一个项目时,右侧的数字向左移动一个位置以填充我们删除时左侧的空白物品。正确的项目现在位于索引处i,因此它实际上不会在迭代中看到,因为接下来发生的事情是我们i为 for 循环的下一次迭代递增。


现在来点聪明的。相反,如果我们向后迭代列表,我们将清除列表:

for item in reversed(mylist):
    mylist.remove(item)

这里的原因是我们在 for 循环的每次迭代中从列表的末尾取出一个项目。由于我们总是从末尾删除项目,因此无需更改任何内容(假设列表中的唯一性——如果列表不是唯一的,则结果是相同的,但参数会变得更复杂一些)。

当然,如果你想从列表中删除所有项目,你可以很容易地做到这一点:

del mylist[:]

甚至使用切片分配:

mylist[:] = []

(我提到后者是因为用其他甚至不需要相同长度的项目替换列表的段可能很有用)。

于 2013-05-09T15:06:01.687 回答
3

那是因为您在迭代列表时正在修改列表,而是迭代浅表副本:

>>> mylist = [1, 2, 3, 4, 5]
>>> for item in mylist[:]:      #use mylist[:] or list(mylist)
            mylist.remove(item)
...     
>>> mylist
[]
于 2013-05-09T15:04:43.387 回答
2

您在循环浏览列表时正在修改您的列表,这是非常糟糕的做法。

于 2013-05-09T15:04:59.950 回答
2

问题是您在迭代列表时正在更改列表。改用列表推导:

mylist = [1, 2, 3, 4, 5]
mylist = [x for x in mylist if condition(x)]
于 2013-05-09T15:05:53.703 回答
0
>>> mylist = [1, 2, 3, 4, 5]

>>> for item in mylist:
        mylist.remove(item)

在这个循环中:第一次它将第 0 个元素 (1) 作为一个项目并将其从 mylist 中删除。所以之后 mylist 将为 [2,3,4,5] 但指针将位于新元素的第一个元素中mylist ([2,3,4,5]) 即 3. 它将删除 3.so 2 不会从列表中删除。

这就是为什么在完整操作后会留下 [2,4] 的原因。

using for loop:-
>>>for i in range(len(mylist)):
       mylist.remove(mylist[0])
       i-=1

>>>mylist
[]

您可以使用 while 循环执行此操作:

>>>mylist = [1, 2, 3, 4, 5]
>>>while (len(mylist)>0):
       mylist.remove(mylist[0])
       print mylist
于 2013-05-09T15:21:49.143 回答
0

使用深拷贝mylist

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

l = [k for k in mylist] # deep copy

for i in range(len(mylist)):
    mylist.remove(l[i])
    print 

print mylist
于 2013-05-11T11:32:07.390 回答