首頁 > 軟體

Python遍歷列表時刪除元素案例

2022-09-06 18:06:33

tk在科學養豬群裡問bluerust、scz是否碰上過這個Python坑,

範例1:

bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5' ]
for ba in bas :
    print( ba )
    if ( ba.find( 'ba' ) != -1 ) :
        bas.remove( ba )
        print( bas )

print( bas )

即遍歷list的過程中動態刪除元素。

上述程式碼輸出如下:

ba1
['ba2', 'ba3', 'ba4', 'ba5']
ba3                             // ba2被跳過去了
['ba2', 'ba4', 'ba5']
ba5                             // ba4被跳過去了
['ba2', 'ba4']
['ba2', 'ba4']                  // 列表未刪乾淨

對範例1做點改動,

範例2:

bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5' ]
for i in range( len( bas ) ) :
    print( i )
    print( bas[i] )
    if ( bas[i].find( 'ba' ) != -1 ) :
        del bas[i]
        print( bas )

print( bas )

上述程式碼輸出如下:

0
ba1
['ba2', 'ba3', 'ba4', 'ba5']
1
ba3
['ba2', 'ba4', 'ba5']
2
ba5
['ba2', 'ba4']
3
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
IndexError: list index out of range
['ba2', 'ba4']

迴圈變數i只遞增到3,進而丟擲IndexError。

該坑的起因是,for迴圈中i的取值從最開始就固定了,實際上要求list在for迴圈中保持不變;遍歷list的過程中動態刪除元素,導致list發生變化,而i仍固執地按原計劃遞增遍歷list,於是漏刪元素、索引越界。

對此,wzhvictor給了5種解決方案。

方式1,利用filter函數

bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
bas = list( filter( lambda ba:ba.find( 'ba' ) == -1, bas ) )
print( bas )

方法2,重新構造list

bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
bas = [ba for ba in bas if ba.find( 'ba' ) == -1]
print( bas )

方法3,遍歷list的拷貝,對原始list進行刪除操作

bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
for ba in bas[:] :
    if ( ba.find( 'ba' ) != -1 ) :
        bas.remove( ba )

print( bas )

方法4

bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
for ba in bas[:] :
    if ( ba.find( 'ba' ) != -1 ) :
        bas.remove( ba )

print( bas )

方法5,倒序遍歷

bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
for i in range( len( bas )-1, -1, -1 ) :
    if ( bas[i].find( 'ba' ) != -1 ) :
        del bas[i]

print( bas )

就tk的範例1而言,方法4其實不適用,方法4適合從list中刪除所有特定值。

這個坑我沒踩過,用過方法2、3、4或者它們的變種。沒像wzhvictor那樣細究過for迴圈中i取值從最開始就固定,但我本能地對迴圈中動態處理的物件不放心,又懶得看Python檔案,所以要麼重新構造list,要麼複製list再操作,完美避坑。今日看了wzhvictor的文章,方法1沒用過,方法5沒想過,方法5比較騷包,我第一次見。

Python表面上的不確定性真多,也沒啥大不了,我的經驗是,能用簡明直觀確定性的寫法,就不要騷包玩花活,效能優化是後話。再就是,單元測試,無需再多強調。

到此這篇關於Python遍歷列表時刪除元素案例的文章就介紹到這了,更多相關Python遍歷列表內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com