python的for可以遍歷乙個list,但是在遍歷的過程中刪除元素常常會得到意想不到的結果甚至程式出現異常,例如:
這段**的本意是想刪除列表中元素為 0 的項,但實際跑起來並不是那個結果。lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6]
for item in lst:
if item == 0:
lst.remove(item)
print lst
輸出: [1, 1, 2, 8, 3, 2, 5, 0, 2, 6]
再看下面這個例子,利用索引來遍歷刪除列表中的元素:
輸出: indexerror: list index out of rangefor item in range(len(lst)):
#此處可以每次迴圈時列印下item 然後就知道結果了
print(item)
if lst[item] == 0:
del lst[item]
print lst
這時候就報錯了,丟擲了陣列下標越界的異常。原因是用for發起任何形式的遍歷時,它的遍歷順序都是從最初就確定的,而在遍歷中刪除了元素會導致當前索引的變化,這樣一是會導致漏刪元素,二是會導致遍歷超過鍊錶的長度。
所以遍歷乙個list時要刪除其中的部分元素就需要其他的解決方案。
方法一:可以使用filter過濾返回新的list
這樣可以安全刪除列表中值為 0 的元素了,filter包括兩個引數,分別是function和list,filter把傳入的函式依次作用於每個元素,然後根據返回值是true還是false來決定是保留還是丟棄該元素。lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6]
lst = filter(lambda x: x != 0, lst)
print lst
方法二:列表解析
方法三:或者遍歷拷貝的list,操作原始的listlst = [x for x in lst if x != 0]
print lst
[:]表示切片的意思,也可以用copy()for item in lst[:]:
if item == 0:
lst.remove(item)
print lst
方法四:用while迴圈來搞定,每次迴圈都先會判斷 0 是否在列表中
方法五:倒序迴圈遍歷while 0 in lst:
lst.remove(0)
print lst
range(len(lst) - 1, -1, -1) 的解釋:len(lst) - 1 起始,第乙個-1 結束,第二個-1 倒序for item in range(len(lst) - 1, -1, -1):
if lst[item] == 0:
del lst[item]
print lst
倒序是最geek的解決辦法,但是倒序的**可讀性差,推薦用filter,這樣寫出來的**更pythonic。
參考:
Python 遍歷列表刪除操作時不能正確刪除
發現元素間隔進行了刪除,這是什麼情況導致的呢?總結當我們遍歷列表中的元素進行刪除操作的時候,發現並不能滿足我們的需求 ls 1 2,3 4,5 for i in ls if i 1 ls.remove i ls 1 3,5 列表的長度變短,對最初的遍歷長度做了修改,導致超出索引 ls 1 2,3 4...
python 語法糖太多 python 語法糖
匿名函式 lamda表示式 def add x,y return x y 等價於f lamda x,y x y f 1,2 三元表示式 wefx 1 y 2 c x if x map對映關係 def square x return x x list x 1,3,10 list r map squar...
Python 的 with 語法糖
python 內建了 sqlite3 模組,可以方便地呼叫 sqlite 資料庫。import sqlite3 conn sqlite3.connect test.db cur conn.cursor cur.execute create table students id bigint prima...