2013-05-09 42 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 
相關問題