【问题标题】:Remove duplicated lists in list of lists in Python删除 Python 列表中的重复列表
【发布时间】:2014-07-14 01:47:58
【问题描述】:

我在这里看到了一些非常相关的问题,但他们的答案对我不起作用。我有一个列表列表,其中一些子列表重复但它们的元素可能是无序的。例如

g = [[1, 2, 3], [3, 2, 1], [1, 3, 2], [9, 0, 1], [4, 3, 2]]

根据我的问题,输出自然应该是:

g = [[1,2,3],[9,0,1],[4,3,2]]

我尝试过使用set,但只删除了那些相等的列表(我认为它应该可以工作,因为集合的定义是没有顺序的)。我访问过的其他问题只有列表完全重复或重复的示例:Python : How to remove duplicate lists in a list of list?。现在输出顺序(对于列表和子列表)不是问题。

【问题讨论】:

  • 您的回答很棒!我正在寻找哪个答案最适合更大的列表

标签: python list python-2.7 set


【解决方案1】:

(ab)使用列表组合的副作用版本:

seen = set()

[x for x in g if frozenset(x) not in seen and not seen.add(frozenset(x))]
Out[4]: [[1, 2, 3], [9, 0, 1], [4, 3, 2]]

对于那些(不像我自己)不喜欢以这种方式使用副作用的人:

res = []
seen = set()

for x in g:
    x_set = frozenset(x)
    if x_set not in seen:
        res.append(x)
        seen.add(x_set)

frozensets 添加到集合的原因是您只能将可散列对象添加到set,而普通sets 不可散列。

【讨论】:

  • 您的回答是最快的。奇怪的是,它给出了想要的输出,但我没有要求。它比@jterrace 答案快两倍。对于 4205 个子列表的列表,您的列表在 0.02 秒内完成。
  • @AlejandroSazo 请检查我的答案与生成器表达式的性能:g = [list(x) for x in set(frozenset(i) for i in (set(i) for i in g))] 我只是对基准感到好奇,很高兴看到它:)
  • @andi 我会尽快做的
【解决方案2】:

如果您不关心列表和子列表的顺序(并且子列表中的所有项目都是唯一的):

result = set(map(frozenset, g))

如果子列表可能有重复项,例如 [1, 2, 1, 3],那么您可以使用 tuple(sorted(sublist)) 而不是 frozenset(sublist),从子列表中删除重复项。

如果要保留子列表的顺序:

def del_dups(seq, key=frozenset):
    seen = {}
    pos = 0
    for item in seq:
        if key(item) not in seen:
            seen[key(item)] = True
            seq[pos] = item
            pos += 1
    del seq[pos:]

例子:

del_dups(g, key=lambda x: tuple(sorted(x)))

In Python, what is the fastest algorithm for removing duplicates from a list so that all elements are unique while preserving order?

【讨论】:

  • +1 好主意!只会添加 [list(x) for x in set(map(frozenset, g))] 以产生 OP 想要的输出。
  • @andi:我将result 保留为一组frozensets,以强调所有子列表和每个子列表中的所有项目都是唯一的,顺序无关紧要。
【解决方案3】:

roippi frozenset 提到的这样使用怎么样:

>>> g = [list(x) for x in set(frozenset(i) for i in [set(i) for i in g])]

[[0, 9, 1], [1, 2, 3], [2, 3, 4]]

【讨论】:

  • 如果性能很重要,您可以将 list comprehension 替换为 generator expresion。只需将[] 替换为() 即可:g = [list(x) for x in set(frozenset(i) for i in (set(i) for i in g))] 有什么区别您可以在此处阅读:stackoverflow.com/questions/47789/…
  • 您的第一种方法(列表理解)使用 0.070491 秒。您使用生成器表达式的方法花费了 0.030556 秒。接受的回答时间是 0.02 秒 :)
【解决方案4】:

我会将列表中的每个元素转换为frozenset(可散列),然后从中创建一个集合以删除重复项:

>>> g = [[1, 2, 3], [3, 2, 1], [1, 3, 2], [9, 0, 1], [4, 3, 2]]
>>> set(map(frozenset, g))
set([frozenset([0, 9, 1]), frozenset([1, 2, 3]), frozenset([2, 3, 4])])

如果您需要将元素转换回列表:

>>> map(list, set(map(frozenset, g)))
[[0, 9, 1], [1, 2, 3], [2, 3, 4]]

【讨论】:

  • 这个答案似乎很快,并且还返回了有序的元组。只错过列表返回:P
  • @AlejandroSazo 查看我的更新答案。我认为它比您接受的更快更简单。
  • 我会尽快的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 2014-06-01
相关资源
最近更新 更多