从列表中获取唯一的列表

7

给定一个列表,我需要返回一个由独特元素组成的列表。我想知道是否有比我想出来的更Pythonic的方法:

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]]

感谢Counter、groupby和defaultdict的解决方案!今天我学到了新东西。 - Yuriy Zubarev
3个回答

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 - Nolen Royalty
3
在这里,将Counter的创建融合到列表推导式中是完全可以的:[[k]*v for k, v in Counter(L).items()] - Karl Knechtel
1
我的经验法则是自动省略那些只被写入一次且只被读取一次的临时变量,除非它们代表着重要的复杂性(“扁平比嵌套好”)。 - Karl Knechtel

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]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接