2012-03-30 67 views
7

給定一個列表,我需要返回唯一項列表的列表。我想看看是否有更Python的方式比我想出了:列表中的唯一列表

def unique_lists(l): 
    m = {} 
    for x in l: 
     m[x] = (m[x] if m.get(x) != None else []) + [x] 
    return [x for x in m.values()]  

print(unique_lists([1,2,2,3,4,5,5,5,6,7,8,8,9])) 

輸出:

[[1], [2, 2], [3], [4], [5, 5, 5], [6], [7], [8, 8], [9]] 
+0

謝謝你的櫃檯,GROUPBY和defaultdict的解決方案!我今天學了些新東西。 – 2012-03-30 04:21:46

回答

9
>>> L=[1,2,2,3,4,5,5,5,6,7,8,8,9] 
>>> from collections import Counter 
>>> [[k]*v for k,v in Counter(L).items()] 
[[1], [2, 2], [3], [4], [5, 5, 5], [6], [7], [8, 8], [9]] 
+1

我最初發布的解決方案只需使用列表的內置計數方法就能縮短一行,但gnibbler使得list.count()爲O(n)的優點成爲我的算法O(n^2)。 +1 – 2012-03-30 04:08:24

+3

沒有理由認爲'計數器'的創建不能被摺疊到這裏的列表理解中:'[[k] * v代表計數器(L).items()中的k,v]'。 – 2012-03-30 04:13:05

+0

@Karl,我同意,我不認爲它的可讀性更差 – 2012-03-30 04:17:06

2

使用默認字典。

>>> from collections import defaultdict 
>>> b = defaultdict(list) 
>>> a = [1,2,2,3,4,5,5,5,6,7,8,8,9] 
>>> for x in a: 
...  b[x].append(x) 
... 
>>> b.values() 
[[1], [2, 2], [3], [4], [5, 5, 5], [6], [7], [8, 8], [9]] 
0

我在功能set()找到構建有用經常:

lst=[1,2,2,3,4,5,5,5,6,7,8,8,9] 

def all_eq_elms(lst, elm): 
    while True: 
     try: 
      yield lst.pop(lst.index(elm)) 
     except: 
      break 

[[e for e in all_eq_elms(lst,elm)] for elm in set(lst)] 

Out[43]: [[1], [2, 2], [3], [4], [5, 5, 5], [6], [7], [8, 8], [9]]