【问题标题】:Python: Remove duplicate lists in list of lists [duplicate]Python:删除列表列表中的重复列表[重复]
【发布时间】:2019-08-22 17:01:50
【问题描述】:

给定的列表看起来像:

list = [["A"], ["B"], ["A","B"], ["B","A"], ["A","B","C"], ["B", "A", "C"]]

如何退货

final_list = [["A"], ["B"], ["A", "B"], ["A", "B", "C"]]

请注意,我将 ["A","B"] 视为与 ["B","A"] 相同 和 ["A","B","C"] 与 ["B", "A", "C"] 相同。

【问题讨论】:

  • 需要维护秩序吗?
  • @Boris 不。顺序无所谓
  • final = list(map(list, set(map(frozenset, l))))

标签: python


【解决方案1】:

试试这个:

list_ = [["A"], ["B"], ["A","B"], ["B","A"], ["A","B","C"], ["B", "A", "C"]]
l = list(map(list, set(map(tuple, map(set, list_)))))

输出

[['A', 'B'], ['B'], ['A', 'B', 'C'], ['A']]

这个过程是这样经历的:

  1. 首先将每个子列表转换为一个集合。因此['A', 'B']['B', 'A'] 都被转换为{'A', 'B'}
  2. 现在将它们中的每一个都转换为一个元组以删除重复项,因为set() 操作无法通过设置列表中的子项来完成。
  3. 使用set() 操作创建唯一元组列表。
  4. 现在将列表中的每个元组项转换为列表类型。

这相当于:

list_ = [['A'], ['B'], ['A', 'B'], ['B', 'A'], ['A', 'B', 'C'], ['B', 'A', 'C']]
l0 = [set(i) for i in list_]
# l0 = [{'A'}, {'B'}, {'A', 'B'}, {'A', 'B'}, {'A', 'B', 'C'}, {'A', 'B', 'C'}]
l1 = [tuple(i) for i in l0]
# l1 = [('A',), ('B',), ('A', 'B'), ('A', 'B'), ('A', 'B', 'C'), ('A', 'B', 'C')]
l2 = set(l1)
# l2 = {('A', 'B'), ('A',), ('B',), ('A', 'B', 'C')}
l = [list(i) for i in l2]
# l = [['A', 'B'], ['A'], ['B'], ['A', 'B', 'C']]

【讨论】:

  • 你也可以l = [list(x) for x in {frozenset(y) for y in my_list}]
  • 这个答案依赖于tuple(set([ ... something ... ])) 总是以相同的顺序返回元素的事实。尽管某些 Python 实现实际上可能是这种情况,但该语言并不能以任何方式保证这一点。我刚刚发现了一个假设被打破的例子:tuple(set([27,28,29,30,31,32,0])) -> (32, 0, 27, 28, 29, 30, 31),而tuple(set([0,27,28,29,30,31,32])) -> (0, 32, 27, 28, 29, 30, 31)
  • 所以,这里总是有效的答案是那些基于排序元素列表的答案,或者使用frozenset,而不是tuple(set(...)) 映射。
【解决方案2】:
l = [["A"], ["B"], ["A","B"], ["B","A"], ["A","B","C"], ["B", "A", "C"]]
[list(i) for i in {tuple(sorted(i)) for i in l}]

【讨论】:

    【解决方案3】:

    一种可能的解决方案:

    lst = [["A"], ["B"], ["A","B"], ["B","A"], ["A","B","C"], ["B", "A", "C"]]
    
    print([
        list(i) 
        for i in sorted(
            set(
                tuple(sorted(i)) 
                for i in lst
            ), 
            key=lambda k: (len(k), k)
        )
    ])
    

    打印:

    [['A'], ['B'], ['A', 'B'], ['A', 'B', 'C']]
    

    【讨论】:

      【解决方案4】:

      当您要处理的数据必须是唯一且无序的时,更好的数据结构选择是setfrozenset

      set 是唯一值的无序容器。

      frozenset 是一个 set,它不能被变异,因此它是可散列的,允许它包含在另一个 set 中。

      示例

      lst = [["A"], ["B"], ["A","B"], ["B","A"], ["A","B","C"], ["B", "A", "C"]]    
      
      data = {frozenset(el) for el in lst}
      
      print(data)
      

      输出

      {frozenset({'B'}), frozenset({'A', 'B'}), frozenset({'A', 'C', 'B'}), frozenset({'A'})}
      

      【讨论】:

        【解决方案5】:

        下面是一个等式分区。它适用于为其定义了相等性的任何类型的任何列表。这比散列分区更糟糕,因为它是二次时间。

        def partition(L, key=None):
        
            if key is None:
                key = lambda x: x
        
            parts = []
            for item in L:
                for part in parts:
                    if key(item) == key(part[0]):
                       part.append(item)
                       break
                else:
                    parts.append([item])
            return parts
        
        def unique(L, key=None):
            return [p[0] for p in partition(L, key=key)]
        
        alist = [["A"], ["B"], ["A","B"], ["B","A"], ["A","B","C"], ["B", "A", "C"]]
        
        unique(alist)
        # results in [['A'], ['B'], ['A', 'B'], ['B', 'A'], ['A', 'B', 'C'], ['B', 'A', 'C']]
        
        unique(alist, key=lambda v: tuple(sorted(v)))
        # results in [['A'], ['B'], ['A', 'B'], ['A', 'B', 'C']]
        

        【讨论】: