2011-07-20 256 views
24

如何使用python檢查列表並刪除所有重複項?我不想指定重複的項目是什麼 - 我想要代碼找出是否有任何並刪除它們,如果是這樣,每個只保留一個實例。如果列表中有多個重複項,它也必須工作。Python:如何從列表中刪除所有重複項目

例如,在我的代碼中,列表lseparatedOrbList有12個項目 - 一個重複六次,一個重複五次,並且只有一個實例。我希望它能夠改變列表,所以只有三個項目 - 每個項目中的一個,並且按照它們之前出現的順序排列。我嘗試這樣做:

for i in lseparatedOrbList: 
    for j in lseparatedOrblist: 
     if lseparatedOrbList[i] == lseparatedOrbList[j]: 
      lseparatedOrbList.remove(lseparatedOrbList[j]) 

但我得到的錯誤:

Traceback (most recent call last): 
    File "qchemOutputSearch.py", line 123, in <module> 
    for j in lseparatedOrblist: 
NameError: name 'lseparatedOrblist' is not defined 

我猜,因爲它是因爲我通過lseparatedOrbList試圖循環,同時通過它,我循環,但我不能想想另一種方式來做到這一點。

+0

你需要保持列表的順序? –

+0

一個常見問題:http://stackoverflow.com/search?q=python+duplicates+list。 –

+0

[如何返回包含沒有重複的公共元素的列表]的可能重複(http://stackoverflow.com/questions/6039009/how-to-return-a-list-containing-common-elements-with-no-重複) –

回答

52

只要創建一個新列表來填充,如果您的列表中的項目尚未在新列表中輸入,那麼只需移至原始列表中的下一個項目即可。

for i in mylist: 
    if i not in newlist: 
    newlist.append(i) 

我認爲這是正確的語法,但我的python有點搖搖晃晃,我希望你至少有這個想法。

+0

工作良好並保持順序,謝謝! – laplacian

+6

好,我想我沒有忘記我所有的蟒蛇,它只有兩年。就像一個警告詞,我很確定這是一個O(n^2)操作,所以你可能不想在大列表上使用它(例如,10,000個項目)。如果你需要它的大名單,我會創建一個哈希表來檢查(O(1),產生一個整體的O(n)實現),而不是檢查列表,但如果你正在處理大型列表,我可能也不想使用python。 –

+0

是的,名單不應該超過15個,所以沒關係。 – laplacian

55

使用set()

woduplicates = set(lseparatedOrblist) 

返回一組無重複。如果您出於某種原因需要返回列表:

woduplicates = list(set(lseperatedOrblist)) 
+12

值得注意的是,如果您的列表中有列表或設置,這將失敗。 –

+7

您還應該明確指出,這不會保留元素順序。 –

3

這是因爲您實際上缺少大寫字母。

故意dedented:

for i in lseparatedOrbList: # capital 'L' 
for j in lseparatedOrblist: # lowercase 'l' 

雖然更有效的方式做到這一點是將內容插入set

如果維持列表順序問題(即,它必須是 「穩定的」),check out the answers on this question

6

這應該爲你做它:

new_list = list(set(old_list)) 

set會自動刪除重複。 list將轉換回列表。

+1

如果原始列表「x」包含列表,則不起作用 – Calimo

24

你可以做到這一點像:

x = list(set(x)) 

例如:如果你做這樣的事情:

x = [1,2,3,4,5,6,7,8,9,10,2,1,6,31,20] 
x = list(set(x)) 
x 

,你會看到下面的結果:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 31] 

有隻有一件事情你應該考慮:結果列表不會按原來的順序排列(將失去公共秩序ocess)。

+1

智能和pythonic :) – mushfiq

+0

如果原始列表'x'包含列表不起作用 – Calimo

5

不,這只是一個錯字,最後的「列表」必須大寫。你可以在同一個變量上嵌套循環(雖然很少有很好的理由)。

但是,代碼還存在其他問題。對於初學者,您正在遍歷列表,因此ij將是不是索引的項目。而且,你不能在迭代它的時候改變一個集合(當然,你可以「運行」,但是瘋狂就在於這種方式 - 例如,你會跳過項目)。然後是複雜性問題,你的代碼是O(n^2)。無論是轉換列表爲set並返回到list(簡單,但打亂剩餘列表項),或做這樣的事情:

seen = set() 
new_x = [] 
for x in xs: 
    if x in seen: 
     continue 
    seen.add(x) 
    new_xs.append(x) 

兩種方案都要求的項目是哈希的。如果這是不可能的,你可能不得不堅持使用目前的方法來解決上述問題。

+0

我剛剛提出了你的答案,但發現你建議列表理解。如果你像這樣使用它,'ys = [x for xs in xs if x not in ys]'',那麼列表理解將不起作用,因爲它基本上將'xs'列表重寫爲'ys'。這是因爲在理解之前訪問的'ys'是分配之前的'ys'。 – Tadeck

+0

@Tadeck:該死,你說得對。接得好。 – delnan

14

這應該是更快,將保留原來的順序:

seen = {} 
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen] 

如果你不關心順序,你可以:

new_list = list(set(my_list)) 
1

爲unhashable名單。它更快,因爲它不會迭代已檢查的條目。

def purge_dublicates(X): 
    unique_X = [] 
    for i, row in enumerate(X): 
     if row not in X[i + 1:]: 
      unique_X.append(row) 
    return unique_X 
0

現代的方式做到這一點維持的順序是:

>>> from collections import OrderedDict 
>>> list(OrderedDict.fromkeys(lseparatedOrbList)) 

由雷蒙德赫廷傑(Python的核心開發)in this answer討論。但是鍵必須是可哈希(這是在你的名單,我認爲這種情況)

2

使用設置

return list(set(result)) 

使用字典

return dict.fromkeys(result).keys() 
-1

還有就是要解決這個問題一個更快的方法:

list = [1, 1.0, 1.41, 1.73, 2, 2, 2.0, 2.24, 3, 3, 4, 4, 4, 5, 6, 6, 8, 8, 9, 10] 
list2=[] 

for value in list: 
    try: 
     list2.index(value) 
    except: 
     list2.append(value) 
list.clear() 
for value in list2: 
    list.append(value) 
list2.clear() 
print(list) 
print(list2) 
2

最簡單的方法是使用set()功能:

new_list = list(set(your_list)) 
-1

這樣一個可以刪除特定項目,其存在多次在列表中:嘗試刪除所有5

list1=[1,2,3,4,5,6,5,3,5,7,11,5,9,8,121,98,67,34,5,21] 
print list1 
n=input("item to be deleted : ") 
for i in list1: 
    if n in list1: 
     list1.remove(n) 
print list1