【问题标题】:removing duplicates of a list of sets删除集合列表的重复项
【发布时间】:2015-11-24 15:26:06
【问题描述】:

我有一个集合列表:

L = [set([1, 4]), set([1, 4]), set([1, 2]), set([1, 2]), set([2, 4]), set([2, 4]), set([5, 6]), set([5, 6]), set([3, 6]), set([3, 6]), set([3, 5]), set([3, 5])]

(实际上在我的例子中是倒数元组列表的转换)

我想删除重复项以获得:

L = [set([1, 4]), set([1, 2]), set([2, 4]), set([5, 6]), set([3, 6]), set([3, 5])]

但如果我尝试:

>>> list(set(L))
TypeError: unhashable type: 'set'

或者

>>> list(np.unique(L))
TypeError: cannot compare sets using cmp()

如何获得具有不同集合的集合列表?

【问题讨论】:

  • 一种方法是将set 的列表转换为listlist,然后删除重复项,然后将list 元素转换回set
  • @ZdaR 我要用粗体字说:你的提示是错误的。按照你的说明“转换@987654330的列表” @ 到listlist,然后删除重复项”,我们得到list(map(list, [{3, 11}, {11, 3}])) 输出[[3, 11], [11, 3]]

标签: python list duplicates set unique


【解决方案1】:

还有另一种选择。

import itertools
list_sets = [set(['a', 'e', 'f']), set(['c', 'b', 'f']), set(['a', 'e', 'f']), set(['a', 'd']), set(['a', 'e', 'f'])]

lists = [list(s) for s in list_sets] # convert a list of sets to a list of lists
lists.sort()
lists_remove_duplicates = [lists for lists,_ in itertools.groupby(lists)]
print(lists_remove_duplicates)

# output
[['a', 'd'], ['a', 'e', 'f'], ['c', 'b', 'f']]

【讨论】:

    【解决方案2】:

    这是另一种选择

    yourNewSet = map(set,list(set(map(tuple,yourSet))))
    

    【讨论】:

    • 这个答案是错误的。两个相等的集合可以映射到两个不同的元组。我已经看到了这种情况。例如:ss = [{3, 11}, {11, 3}]; list(map(tuple, ss)) 输出 [(3, 11), (11, 3)]
    【解决方案3】:

    使用循环的替代方法:

    result = list()
    for item in L:
        if item not in result:
            result.append(item)
    

    【讨论】:

    • 创建列表最好使用[]而不是list()
    • @ReblochonMasque:这是因为[] 是文字语法(允许在编译时实例化空列表)而list() 是函数调用(必须在运行时查找函数名称然后调用以返回空列表)。后者稍贵。
    • 我对@9​​87654327@ 的偏爱仅仅是审美。直到今天我什至不知道它稍微贵了一点。如果这是唯一的问题,我认为这没什么大不了的。
    • @ReblochonMasque 我调查了一点,they behave differently,但正如你所说,这是一个微不足道的区别。
    • @thefourtheye 我认为这有点牵强,除非我遗漏了什么。你必须犯错误分配给list而不是分配list()
    【解决方案4】:

    最好的方法是将您的集合转换为frozensets(可散列),然后使用set 仅获取唯一集合,像这样

    >>> list(set(frozenset(item) for item in L))
    [frozenset({2, 4}),
     frozenset({3, 6}),
     frozenset({1, 2}),
     frozenset({5, 6}),
     frozenset({1, 4}),
     frozenset({3, 5})]
    

    如果你想要它们作为集合,那么你可以像这样将它们转换回sets

    >>> [set(item) for item in set(frozenset(item) for item in L)]
    [{2, 4}, {3, 6}, {1, 2}, {5, 6}, {1, 4}, {3, 5}]
    

    如果您还希望保持订单,同时删除重复项,那么您可以使用collections.OrderedDict,像这样

    >>> from collections import OrderedDict
    >>> [set(i) for i in OrderedDict.fromkeys(frozenset(item) for item in L)]
    [{1, 4}, {1, 2}, {2, 4}, {5, 6}, {3, 6}, {3, 5}]
    

    【讨论】:

    • @PM2Ring 它存在于 2.7 中,因此该陈述并非严格正确。
    • @DanD:哎呀!我最初只是查看Python 3 docs,上面写着“3.1 版中的新功能”。但我刚刚检查了 Python 2 文档,上面写着“2.7 版中的新功能”;我应该在那里检查它是否已被反向移植。对于那个很抱歉。我会删除我的评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    • 2015-02-20
    • 1970-01-01
    相关资源
    最近更新 更多