Python語法糖 遍歷列表時刪除元素

2021-10-01 23:12:50 字數 1655 閱讀 2529

python的for可以遍歷乙個list,但是在遍歷的過程中刪除元素常常會得到意想不到的結果甚至程式出現異常,例如:

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]

這段**的本意是想刪除列表中元素為 0 的項,但實際跑起來並不是那個結果。

再看下面這個例子,利用索引來遍歷刪除列表中的元素:

for item in range(len(lst)):

#此處可以每次迴圈時列印下item 然後就知道結果了

print(item)

if lst[item] == 0:

del lst[item]

print lst

輸出: indexerror: list index out of range

這時候就報錯了,丟擲了陣列下標越界的異常。原因是用for發起任何形式的遍歷時,它的遍歷順序都是從最初就確定的,而在遍歷中刪除了元素會導致當前索引的變化,這樣一是會導致漏刪元素,二是會導致遍歷超過鍊錶的長度。

所以遍歷乙個list時要刪除其中的部分元素就需要其他的解決方案。

方法一:可以使用filter過濾返回新的list

lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6]

lst = filter(lambda x: x != 0, lst)

print lst

這樣可以安全刪除列表中值為 0 的元素了,filter包括兩個引數,分別是function和list,filter把傳入的函式依次作用於每個元素,然後根據返回值是true還是false來決定是保留還是丟棄該元素。

方法二:列表解析

lst = [x for x in lst if x != 0]

print lst

方法三:或者遍歷拷貝的list,操作原始的list

for item in lst[:]:

if item == 0:

lst.remove(item)

print lst

[:]表示切片的意思,也可以用copy()

方法四:用while迴圈來搞定,每次迴圈都先會判斷 0 是否在列表中

while 0 in lst:

lst.remove(0)

print lst

方法五:倒序迴圈遍歷

for item in range(len(lst) - 1, -1, -1):

if lst[item] == 0:

del lst[item]

print lst

range(len(lst) - 1, -1, -1) 的解釋:len(lst) - 1 起始,第乙個-1 結束,第二個-1 倒序

倒序是最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...