2016-03-13 38 views
2

我很好奇,如果您可以從列表中刪除重複項並將唯一身份證作爲列表返回。我想這一點:使用list comprehension從列表中刪除重複項

def do_list(lists): 
    res = [ [ one for one in temp if one not in res ] for temp in lists ] 
    return res 

因此,例如,如果:

lists = [ [ "a","b","c" ],[ "d","a" ],[ "c","a","f" ] ] 

的結果應該是:

[ "a","b,"c","d","f" ]  

但它給我,我分配新建分配FY之前REFFERENCE可變資源錯誤。

回答

2

你,因爲你引用res的理解裏面得到一個錯誤。這不起作用,因爲res僅在表達式完成後纔可用。

由於我是一個好奇的排序,因爲標題問:「通過使用列表理解去除名單列表重複」,我想看看你能不能用這個只一個列表理解做的,而不是由作弊如使用itertools:對

而且這裏是如何:

>>> lists = [ [ "a","b","c" ],[ "d","a" ],[ "c","a","f" ] ] 
>>> lists2 = sorted(sum(lists, [])) 
>>> [ item for i, item in enumerate(lists2) if i == 0 or i == len(lists2) or lists2[i - 1] != item ] 
['a', 'b', 'c', 'd', 'f'] 

更多瘋狂,你可以結合他們在同一行,但你必須重複sum()sorted() CA LLS。我不能動我自己去寫這麼醜陋的代碼;-)

  • sum(lists, [])將扁平化列表;它返回lists中所有項目的總和(+運算符),[]作爲初始列表。
  • sorted()將對其進行排序。這是必需的,因爲我們只檢查最後一個項目
  • if聲明檢查前一個項目是否與當前項目相同。

但這是醜陋的,不pythonic。 對於Guido的愛,使用Slayer的回答(或其中的一些變化)!

+0

這很美麗,謝謝。 – TheTask1337

+2

@TheTask1337不確定「美麗」是否適合描述這類代碼;-)它看起來像一個Perl程序員會做的事情! :p就像我說的,這只是一個教育練習。請不要實際使用它;-) – Carpetsmoker

7

你可以這樣做:

set(itertools.chain.from_iterable(lists)) 

set將刪除所有重複的set的內部剛剛平整列表(S)到一個列表。

+1

或'set(itertools.chain(* lists))',少一些字符。 –

+0

謝謝!那麼使用簡單的列表理解不可能做到嗎? – TheTask1337

1

res只有在整個列表理解被評估之後纔會被創建。如果你需要它有序

res = list(set(sum(lists, []))) 

res = sorted(set(sum(lists, []))) 

如果你想它下令究竟是如何來的時候,列表理解可能不是最好的方式,你可以使用一個set刪除重複。相反,這樣做:

res = [] 
for temp in lists: 
    res.append([]) 
    for one in temp: 
     if one not in res[-1]: 
      res[-1].append(one) 
+0

恕我直言,使用'sum(列表,[])'是更加明顯的方式來創建一個扁平列表... – Carpetsmoker

+0

@Carpetsmoker:這可能是顯而易見的,但也許我沒有大量的情報。謝謝你提到它。 – zondo