2012-03-30 65 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]]