2013-05-09 23 views
2

在我的Python 2.7.2 IDLE解释:为什么list.remove只能删除每个第二项?

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

>>> mylist 
[2, 4] 

为什么?

+0

而你遍历它不改变你的列表中的深拷贝.... – 2013-05-09 15:04:40

+0

顺便说一句,我在另一个问题上看到,正确的方法是del mylist [:] – Scruffy 2013-05-09 15:05:09

回答

4

这是因为当你遍历一个列表,python keeps track of the index in the list。请看下面的代码来代替:

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

如果我们跟踪的(这基本上是什么Python是在你的代码做),那么我们看到,当我们删除列表中的一个项目,在右边的数字移动一个在我们移除物品时,左边的位置填满了剩下的空位。正确的项目现在在索引i,因此它将永远不会在迭代中看到,因为接下来发生的事情是我们为for循环的下一次迭代增加i


现在有点聪明。相反,如果我们遍历列表落后,我们会清除列表:

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

这里的原因是,我们在for循环的每个迭代采取一个项目从名单的末尾。既然我们总是把项目拿走,没有什么需要改变的(假设列表中有唯一性 - 如果列表不是唯一的,结果是一样的,但是参数变得更复杂一些)。

当然,如果你正在寻找从列表中删除所有的项目,你能做到这一点真的很容易:

del mylist[:] 

甚至有片分配:

mylist[:] = [] 

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

+0

我喜欢Python,但有一些奇怪的变体需要对底层实现/概念有相当深入的理解。 – Scruffy 2013-05-09 15:08:16

3

那是因为你正在修改的列表,同时遍历它,遍历一个浅拷贝,而不是:

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

您正在修改您的列表,而你是通过它的循环,这是非常不好的做法。

2

问题在于,您在迭代时正在更改列表。使用列表理解来代替:

mylist = [1, 2, 3, 4, 5] 
mylist = [x for x in mylist if condition(x)] 
+1

这不是未定义的行为。 – mgilson 2013-05-09 15:06:12

+0

Python规范没有提到在这种情况下会采用什么行为,所以它是一个实现细节,因此未定义。如果我愿意,我可以编写一个Python虚拟机,在这种情况下爆炸,它仍然符合规范。 – 2013-05-09 15:11:23

+1

规范*确实*指明了这是如何工作的。我不记得在哪里,但有一点我记得搜索它,并发现它明确拼写出来。 – mgilson 2013-05-09 15:12:55

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

>>> for item in mylist: 
     mylist.remove(item) 
在这个循环

: 第一时间将需要第0个元素(1)作为项目和MYLIST后从mylist.so除去这将是[2,3,4,5],但指针将在新mylist([2,3,4,5])的第1个元素中,它是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 
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 
相关问题