2011-10-26 47 views
4

我嘗試了一些事情列出了交互式解釋,我注意到了這一點:列表「怪癖」

>>> list = range(1, 11) 
>>> for i in list: 
...  list.remove(i) 
... 
>>> list 
[2, 4, 6, 8, 10] 

任何人都可以解釋爲什麼它留下偶數?這讓我很困惑......非常感謝。

+0

對於列表[:]中的列表[或列表中的列表],應該解決您的問題,因爲第一個將創建片副本,或者第二個將創建新的不可變對象(元組)。 –

+1

標準警告:將列表命名爲「list」是個不好的習慣,因爲這會破壞內置類型列表。 – DSM

+0

好點! :)當我將它命名爲「list」時,我沒有想到它。 (可能與作者命名他的「列表」) –

回答

4

我的猜測是,for循環等實現如下:

list = range(1, 11) 

i = 0 
while i < len(list): 
    list.remove(list[i]) 
    i += 1 

print(list) 

每次元素被刪除,「下一個」元素滑入其位置,但是i得到反正遞增,跳過2種元素。

但是,是的,ObscureRobot是正確的,這是不是真的安全(這可能是未定義的行爲)。

+0

實際上,它的定義與OP所顯示的一樣。 – PaulMcG

+0

@Paul對不起,我的意思是for循環代碼是未定義的,至少根據Python文檔 – Owen

3

如果你想從後到前修改的列表,同時遍歷它,工作方式:

lst = range(1, 11) 
for i in reversed(lst): 
    lst.remove(i) 
+0

爲什麼這會起作用?這是一個很好的解決方案... – Bridgo

+0

@Bridgo。如果您從列表的前面移除一個項目,則所有其他項目必須向下移動;但如果您從後面移除,其他項目保持不變。 – ekhumoro

+0

啊..非常感謝。這很有道理。 – Bridgo

2

我覺得這是最簡單的用Python解釋:

>>> for iteration, i in enumerate(lst): 
...  print 'Begin iteration', iteration, 'where lst =', str(lst), 'and the value at index', iteration, 'is', lst[iteration] 
...  lst.remove(i) 
...  print 'End iteration', iteration, 'where lst =', str(lst), 'with', i, 'removed\n' 
... 
Begin iteration 0 where lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and the value at index 0 is 1 
End iteration 0 where lst = [2, 3, 4, 5, 6, 7, 8, 9, 10] with 1 removed 

Begin iteration 1 where lst = [2, 3, 4, 5, 6, 7, 8, 9, 10] and the value at index 1 is 3 
End iteration 1 where lst = [2, 4, 5, 6, 7, 8, 9, 10] with 3 removed 

Begin iteration 2 where lst = [2, 4, 5, 6, 7, 8, 9, 10] and the value at index 2 is 5 
End iteration 2 where lst = [2, 4, 6, 7, 8, 9, 10] with 5 removed 

Begin iteration 3 where lst = [2, 4, 6, 7, 8, 9, 10] and the value at index 3 is 7 
End iteration 3 where lst = [2, 4, 6, 8, 9, 10] with 7 removed 

Begin iteration 4 where lst = [2, 4, 6, 8, 9, 10] and the value at index 4 is 9 
End iteration 4 where lst = [2, 4, 6, 8, 10] with 9 removed 

請注意,這是一個壞想法:(a)在遍歷它時修改list;(b)調用list「列表」。