引發問題的場景
今天在寫一個小游戲的demo時,進行游戲元素操作時,遇到了一個問題.類似下面代碼:
list = ['a','b','c','d'] # element_type == list
for i in list:
print('元素的下標為{},元素的值{}'.format(list.index(i),list)) # 打出內容.方便查看
list.remove(i)
print(list)
本意是遍歷刪除list中的所有元素.最后list應該為一個空數組.
但是代碼實際運行結果是
元素的下標為0,元素的值['a', 'b', 'c', 'd']
元素的下標為1,元素的值['b', 'c', 'd']
['b', 'd'] # 余下兩個元素
問題分析
很明顯的是,在list中只刪除了前兩個元素['a','b']
,但是本意是刪除所有元素.
也就是for循環是執行了兩次,而非四次.
- 我猜想問題可能是這樣的:
- 在進入for循環的時候,循環下標是遞增的.
- 而在for循環操作list的時候(上面代碼的刪除),list中的元素是動態發生變化的.(當list.remove(list_elem)的時候,len(list)已經發生變化.)
循環下標遞增,而循環元素在動態變化.就造成了上面的結果.
換一種循環遍歷的方式:
for i in range(len(list)):
list.remove(list[i])
如上面的代碼,如果強制指定i,就會報錯:下標超出.這是因為強制指定了循環次數.
解決辦法
遍歷在新的列表操作,刪除是在原來的列表操作
a = [1,2,3,4,5,6,7,8]
print(id(a)) # 兩個元素的id不相同
print(id(a[:])) # 兩個元素的id不相同
for i in a[:]:
if i>5:
pass
else:
a.remove(i)
print(a)
print('-------------------------')
print(id(a))