有没有一种方法可以基于嵌套列表删除重复的列表项目,而与嵌套列表项目的顺序无关?

时间:2019-10-08 01:04:54

标签: python duplicates nested-lists

我正在尝试从包含嵌套列表组合和浮点值的嵌套列表中删除重复项:

list = [
[['Milk', 'Bread', 'Diaper'], 40.0], 
[['Milk', 'Diaper', 'Bread'], 40.0], 
[['Milk', 'Diaper', 'Beer'], 40.0], 
[['Milk', 'Beer', 'Diaper'], 40.0], 
[['Diaper', 'Bread', 'Milk'], 40.0], 
[['Diaper', 'Bread', 'Beer'], 40.0], 
[['Diaper', 'Milk', 'Bread'], 40.0], 
[['Diaper', 'Milk', 'Beer'], 40.0], 
[['Diaper', 'Beer', 'Bread'], 40.0], 
[['Diaper', 'Beer', 'Milk'], 40.0], 
[['Beer', 'Bread', 'Diaper'], 40.0], 
[['Beer', 'Milk', 'Diaper'], 40.0], 
[['Beer', 'Diaper', 'Bread'], 40.0], 
[['Beer', 'Diaper', 'Milk'], 40.0]
]

无论嵌套列表中项目的顺序如何,我都必须能够基于删除嵌套列表的重复项来从外部列表中删除项目。

输出必须是每个组合的一个实例:

updated_list = [
[['Milk', 'Bread', 'Diaper'], 40.0],
[['Diaper', 'Beer', 'Bread'], 40.0], 
[['Beer', 'Diaper', 'Milk'], 40.0]
]

谢谢。

2 个答案:

答案 0 :(得分:1)

您可以为此使用Python的setfrozenset

seen_it = set()
updated_list = []
for line in list:
    key = frozenset(line[0])
    if key not in seen_it:
        seen_it.add(key)
        updated_list.append(line)

请注意,seen_it会跟踪我们之前看到的子列表,以避免添加到updated_list中的唯一行中。

还要注意,seen_it中的键是frozenset类型,它会忽略set之类的顺序,但是它是不可变的,因此可以进入另一个集合。

答案 1 :(得分:0)

您可以使用set,或者,如果子列表可以包含重复的元素,则可以使用collections.Counter

集合是唯一元素的无序集合,因此{1, 2, 3}等效于{3, 2, 1}。如果将列表传递给set,它将创建一个包含列表元素的集合。但是,如果相同的值两次出现在列表中,则该信息将丢失在集合中。

# These are both the set {1, 2, 3}
s1 = {3, 1, 2, 1}
s2 = set([2, 1, 3, 3, 2])
assert s1 == s2 # True

如果列表中可能有重复项,则需要的数据类型是多集。不幸的是,Python没有提供多集。但是,Counter适用于多重集的许多用例,包括比较。

from collections import Counter
# These counters have different numbers of each value
c1 = Counter(['a', 'b', 'a', 'c'])
c2 = Counter(['c', 'b', 'b', 'a', 'c'])
assert c1 == c2 # False

对于实际删除重复项,Itertools Recipe unique_everseen应该可以满足您的需求。如果您不关心其他列表元素中的重复项,则可以将operator.itemgetter用作key函数。


此外,您不应使用“列表”作为变量名; it's bad to shadow the builtins