Python遍歷列表刪除多個元素或者重復元素


在遍歷list的時候,刪除符合條件的數據,結果不符合預期

 
num_list = [1, 2, 2, 2, 3]
print(num_list)

for item in num_list:
    if item == 2:
        num_list.remove(item)
    else:
        print(item)

print(num_list)

結果是

[1, 2, 2, 2, 3]
1
[1, 2, 3]

或者有:

 
num_list = [1, 2, 3, 4, 5]
print(num_list)

for i in range(len(num_list)):
    if num_list[i] == 2:
        num_list.pop(i)
    else:
        print(num_list[i])

print(num_list)
 

結果報錯:

 

[1, 2, 3, 4, 5] Traceback (most recent call last): 1
4
5 File "tes.py", line 5, in <module>
    if num_list[i] == 2: IndexError: list index out of range Process finished with exit code 1

 

 

 

原因是,刪除list中的元素后,list的實際長度變小了,但是循環次數沒有減少,依然按照原來list的長度進行遍歷,所以會造成索引溢出。

1.把列表拷貝,然后對原列表進行刪除操作就沒問題了

 

num_list = [1, 2, 2, 2, 3]
print(num_list)

for item in num_list[:]:
    if item == 2:
        num_list.remove(item)
    else:
        print(item)

print(num_list)

 

 

 

 結果:

[1, 2, 2, 2, 3]
1
3
[1, 3]

num_list[:]是對原始的num_list的一個拷貝,是一個新的list,所以,我們遍歷新的list,而刪除原始的list中的元素,則既不會引起索引溢出,最后又能夠得到想要的最終結果。此方法的缺點可能是,對於過大的list,拷貝后可能很占內存。

2.從后往前遍歷列表,刪除

3.filter函數

例子 list中去空字符(配合lambda表達式):

condition = lambda t: t != "" (判斷符合條件很復雜就不能使用lambda,自己寫方法吧)

filter_list = list(filter(condition, list)

Python的List的底層是實現是一個PyObject*數組。如果每次增加一個元素都擴張內存的話效率太低,在增加元素的時候所以會有預申請內存。同理刪除元素的時候也不是馬上就減小內存空間,他會按照一定的策略減小。而這種減小不太好預測。
再加上刪除后索引如何調整並沒有明確定義。比如一個長度為3的List你刪除了第2個那么第三個下標應該是2還是3,等等可能會引發歧義。如果這個時候內存達到了需要減小的條件,迭代器就不太好判斷新的索引究竟是多少。
所以Python為了通用性和安全性考慮就禁止在遍歷時刪除元素了。

 

Python 去除列表中重復的元素

 

比較容易的是用內置的set

l1 = ['b','c','d','b','c','a','a'] 
l2 = list(set(l1)) 
print l2

還有一種據說速度更快的,沒測試過兩者的速度差別

l1 = ['b','c','d','b','c','a','a'] 
l2 = {}.fromkeys(l1).keys() 
print l2

這兩種都有個缺點,祛除重復元素后排序變了:

['a', 'c', 'b', 'd'] 

如果想要保持他們原來的排序:

用list類的sort方法

l1 = ['b','c','d','b','c','a','a'] 
l2 = list(set(l1)) 
l2.sort(key=l1.index) 
print l2

也可以這樣寫

l1 = ['b','c','d','b','c','a','a'] 
l2 = sorted(set(l1),key=l1.index) 
print l2

也可以用遍歷

l1 = ['b','c','d','b','c','a','a'] 
l2 = [] 
for i in l1: 
if not i in l2: 
        l2.append(i) 
print l2

上面的代碼也可以這樣寫

l1 = ['b','c','d','b','c','a','a'] 
l2 = [] 
[l2.append(i) for i in l1 if not i in l2] 
print l2

這樣就可以保證排序不變了:

['b', 'c', 'd', 'a']

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM