2013-07-28 124 views
0

比如我有一個列表:Python - 如何從列表中刪除相似的元素?

L = [1, 2, 2, 3, 1, 1, 6, 10, 1, 3] 

,我想從列表中刪除所有1級的,所以我會得到:

L = [2, 2, 3, 6, 10, 3] 

我試圖遍歷列表,然後刪除元素,如果它等於我想要刪除的元素(在這種情況下是1),但事實證明你不能同時從列表中迭代和刪除東西,因爲它會混淆計數。我提出的最好的事情就是構造一個新的列表L2,它不包含任何1的列表,然後將它放入L中,但是有沒有解決方案只涉及變異L?

+0

事實上,我們對此深感抱歉:d –

回答

5

但有沒有解決方案,只涉及突變L?

您可以迭代您的List - L[:]的副本,並從L中刪除元素。這不會搞亂計數。

如果你真的不想創建一個新的列表,你將不得不使用range(len(L) - 1, -1, -1)反向迭代,但那不會是'Pythonic'了。

>>> for x in L[:]: 
...  if x == 1: 
...   L.remove(x) 
... 
>>> L 
[2, 2, 3, 6, 10, 3] 

但是,您也可以使用列表綜合

>>> L = [1, 2, 2, 3, 1, 1, 6, 10, 1, 3] 
>>> L[:] = [x for x in L if x != 1] 
>>> L 
[2, 2, 3, 6, 10, 3] 
+0

'L [:] = [x對於...]' –

+1

什麼是使用'L [含義:: -1]'不'L [:]'?這是'L'的新副本,反向或不反向並不重要。 – zhangyangyu

+0

@張揚餘。是的,沒有區別。無論如何,我已經用更明智的文字更新了答案。 ;) –

1

使用過濾器內置:

>>> L = [1, 2, 2, 3, 1, 1, 6, 10, 1, 3] 
>>> filter(lambda x: x is not 1, L) 
[2, 2, 3, 6, 10, 3] 

也可以分配回L

>>> L = [1, 2, 2, 3, 1, 1, 6, 10, 1, 3] 
>>> L = filter(lambda x: x is not 1, L) 
>>> L 
[2, 2, 3, 6, 10, 3] 

你也可以換這個概念到方法,以便能夠指定項目包括列表/排除:

def exclude(collection, exclude_list): 
    return filter(lambda x: x not in exclude_list, collection) 

def include(collection, include_list): 
    return filter(lambda x: x in include_list, collection) 

>>> L = [1, 2, 2, 3, 1, 1, 6, 10, 1, 3] 
>>> L = exclude(L, [1]) 
>>> L 
[2, 2, 3, 6, 10, 3] 
+1

在這個時代使用過濾器並不是真正的pythonic *和*不能解決創建新列表而不是改變現有列表的問題。 – Voo

+0

將列表從A變爲B,或者創建B並將其分配給A並沒有真正的區別。如果正確完成。 –

+0

我邀請您創建一個非常大的列表,並在嘗試兩種不同的方法時查看您的內存消耗情況。即使「正確完成」(無論這意味着什麼),它佔用內存兩倍的固有問題是不可能避免的[至少在python中,非常聰明的編譯器可能會做一些技巧,但我懷疑任何語言/編譯器組合做這樣的atm)。 – Voo

0

如果你不想改變列表或生成任何新的副本。您可以從結束循環開始和使用指標:

>>> for i in range(len(L)-1, -1, -1): 
...  if L[i] == 1: 
...   del L[i] 
+0

謝謝。我混淆了'pop'的輸出。 – zhangyangyu

0

這是尷尬的蟒蛇做未做列表的副本...

這將做到這一點不進行復制。

a = range(6) # Some array [0,1,2,3,4,5] 
i=0 
while i < len(a): 
    if a[i] == 4: 
    del a[i] 
    else: 
    i += 1 

輸出

>>> a 
[0, 1, 2, 3, 5] 
相關問題