我有以下代碼,它只使用for循環刪除列表的一半。爲什麼會發生?另外,我應該如何刪除列表中的第一個元素,然後遍歷它?爲什麼在for循環中的del列表[0]只能刪除列表的一半?
list = [1,2,3,4,5,6,7,8,9,10]
for x in list:
print list[0]
del list[0]
print list
輸出:
1
2
3
4
5
[6, 7, 8, 9, 10]
我有以下代碼,它只使用for循環刪除列表的一半。爲什麼會發生?另外,我應該如何刪除列表中的第一個元素,然後遍歷它?爲什麼在for循環中的del列表[0]只能刪除列表的一半?
list = [1,2,3,4,5,6,7,8,9,10]
for x in list:
print list[0]
del list[0]
print list
輸出:
1
2
3
4
5
[6, 7, 8, 9, 10]
的問題是,你從列表中刪除,但該列表迭代器不知道,並愉快地處理「剩餘」列表中。
因此,在第一次迭代中,迭代器位於索引0處,並且在下一次迭代時刪除索引0,迭代器返回索引1(在刪除第一個項目之前,索引2處的項目),並刪除索引0.在下一次迭代中,您獲取索引2處的項目(最初位於索引4處,但因爲您刪除了兩個項目,現在位於索引2處),依此類推。最後,只要索引大於列表中剩餘的項目,它就會停止,因爲您爲在原始列表中間(一半)處理的每個項目移除了一個項目。
長話短說:不要修改你正在迭代的列表。
如果你真的想這樣做類似的東西,那麼你可以使用一個while
循環:
lst = [1,2,3,4,5,6,7,8,9,10]
while lst: # as long as the lst contains items
print lst[0]
del lst[0]
print lst
或遍歷一個副本:
lst = [1,2,3,4,5,6,7,8,9,10]
for x in lst[:]: # [:] makes a shallow copy of a list
print lst[0]
del lst[0]
print lst
注:list
是名Python的一個內置函數,所以如果你有一個名字相同的變量,你就會影響這個函數。這就是爲什麼我將變量名改爲lst
。
這裏發生的事情是,你是因爲你迭代它改變了列表,讓我們看看循環迭代
1st iteration:
pointer
|
V
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
現在你刪除列表中的號碼1,但指針也將移動到下一個項目,這就是問題所在
2nd iteration:
pointer
|
V
[2, 3, 4, 5, 6, 7, 8, 9, 10]
下一迭代數2將被刪除,該指針將前進。
3rd iteration:
pointer
|
V
[3, 4, 5, 6, 7, 8, 9, 10]
4th iteration:
pointer
|
V
[4, 5, 6, 7, 8, 9, 10]
5th iteration (last one):
pointer
|
V
[5, 6, 7, 8, 9, 10]
現在您打印列表並獲取[6,7,8,9,10]。你可以看到,我所說的實際上是通過將print list[0]
行更改爲print list[0], x
而發生的,這樣你可以看到指針。
這將是輸出:
1 1
2 3
3 5
4 7
5 9
[6, 7, 8, 9, 10]
可以做些什麼來解決這個問題?以下的任何一個:這意味着該環將具有len(list)
迭代
這將使x
一個數字(在列表中的項目的索引)(這將是10次迭代)
list = [1,2,3,4,5,6,7,8,9,10]
for x in range(len(list)):
print list[0]
del list[0]
print list
這將使循環迭代原始列表的副本,因此它將循環10次,這足以刪除列表中的所有項目。
list = [1,2,3,4,5,6,7,8,9,10]
copy = [1,2,3,4,5,6,7,8,9,10]
for x in copy:
print list[0]
del list[0]
print list
你改變在循環使用的名單,在副本上工作,以避免這種 – PRMoureu
不要修改你迭代一個列表 - 你的迭代器被搞砸了。另外:不要使用'list'作爲變量名,它會隱藏內建在'list'類型中的pythons。 – AChampion
嘗試:'對於範圍內的x(len(list)):'代替;) – alfasin