2012-12-18 55 views
6

我是新來的Python與列表 我使用Python 3.2.3(默認情況下,2012年10月19日,20實驗: 13:42)[GCC 4.6.3]上linux2上爲什麼一個for循環彈出式法(或del語句)不遍歷所有列表元素

這裏是我的samplecode

>>> l=[1,2,3,4,5,6] 
>>> for i in l: 
...  l.pop(0) 
...  print(l) 
... 

我希望下面的輸出

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

相反,我得到這個

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

的for循環停止後3圈迭代。有人可以解釋爲什麼嗎?

+0

可能重複的[迭代修改列表](http://stackoverflow.com/questions/1637807/modifying-list-while-iterating) –

+0

@NedBatchelder:儘管根本原因是相同的,但問題是顯着不同的。調用'pop'的原因甚至不一樣(鏈接正試圖跳過,這不是)。 – Guvante

回答

5

展開位(插入符號(^)是在循環 「指數」):

your_list = [1,2,3,4,5,6] 
      ^

突然離開第一個項目後:

your_list = [2,3,4,5,6] 
      ^

現在繼續循環:

your_list = [2,3,4,5,6] 
      ^

現在彈出第一項:

your_list = [3,4,5,6] 
      ^

現在繼續循環:

your_list = [3,4,5,6] 
       ^

現在流行過的第一個項目:

your_list = [4,5,6] 
       ^

現在繼續循環 - 等待,我們就大功告成了。 :-)


>>> l = [1,2,3,4,5,6] 
>>> for x in l: 
...  l.pop(0) 
... 
1 
2 
3 
>>> print l 
[4, 5, 6] 
+2

真的嗎?拼寫錯誤?呵呵......我一直認爲這是因爲它看起來像一個顛倒的胡蘿蔔......每天學習新的東西...... – mgilson

1

Python不支持改變一個列表的長度,而你遍歷它。修改副本或使用list comprehension代替。

想想Python是如何真正做的for循環 - 它通過元素計數,目前指數在返回的項目。當你刪除一個,索引意味着一個不同的元素。

+0

有一種情況可能會起作用。在每次迭代中彈出最後一個元素時。 –

+0

潛在的情況下,它可以工作。這不是你應該依賴的東西,但有更好的方法。 –

+2

Python確實支持在迭代列表時修改列表,並且一旦理解了發生的事情,它將以一致且可預測的方式工作。順便說一句,對於一些使用情況,另一個有用的解決方法是以相反的順序在列表上進行操作。 – kindall

2

你必須要小心,試圖修改你迭代集合時。在這種情況下,列表用一個簡單的整數索引來跟蹤「當前位置」。當您使用pop(),一切都改變了指數等元素被跳過。

在循環的第一次迭代中,i是L [0]。然後你彈出的列表中,那麼你訪問L [1],這是最初以1 [2]。然後你彈出列表,並且下一次迭代訪問l [2],這是l [4]中的過去[012],在你的真實代碼中更復雜。

-1

你可以使用一個while循環而不是for循環完成這個任務。

while len(some_list)>0 : 
    some_list.pop(0) 

一個for循環將列表中的每個項目,這將無法正常工作,在列表中的索引將與每個缺失改變實際迭代,你會不會最終得到的所有項目。

但是,每當循環運行時,while循環都會檢查一個條件,如果仍然爲真,請再次運行代碼。這裏我們指定列表的長度必須大於0,即列表中必須有內容。