如何确定一个列表是否包含另一个列表?

时间:2018-05-04 17:30:33

标签: python list

是否有内置的Pythonic方法来确定一个列表是否完全包含另一个列表的内容,包括重复的条目但忽略了项目的顺序?

>>> l1 = [2, 2, 3]
>>> l2 = [2, 2]
>>> l3 = [3, 2]
>>> l4 = [2, 2, 2]
>>> l5 = [2, 5, 2]

>>> is_superset(l1, l2)
True
>>> is_superset(l1, l3)
True
>>> is_superset(l1, l4)
False
>>> is_superset(l1, l5)
False

4 个答案:

答案 0 :(得分:10)

如果没有重复项,或重复项无关紧要(也就是说,如果您的l1l3都是彼此的超集),那么您只需使用集合。但是,如果你希望l1成为l3的正确超集,那你就是在谈论多重集合。幸运的是,Counter已经为您实现了多字符集:

from collections import Counter
def is_superset(a, b):
    return not Counter(b) - Counter(a)

请注意,这个-是多集之间正确的多集差异(正如-set s之间的正确集合差异),而不是跨越dicts的元素减法。因此,如果你减去一个超(多)集,你会得到一个空的multiset(即Counter() - 就像Python中的所有空集合一样,是假的。)

现在:

>>> is_superset(l1, l2)
True
>>> is_superset(l1, l3)
True
>>> is_superset(l1, l4)
False
>>> is_superset(l1, l5)
False

加:

>>> is_superset(l3, l1)
False

答案 1 :(得分:4)

以下是使用Counter

的解决方案
from collections import Counter

def is_superset(l1, l2):
    c1, c2 = Counter(l1), Counter(l2)
    return all(c1[k] >= c2[k] for k in c2)

答案 2 :(得分:3)

使用Counter和内置交集方法的另一种解决方案:

from collections import Counter

def is_superset(l1, l2):
    c1, c2 = Counter(l1), Counter(l2)
    return c1 & c2 == c2

测试:

>>> l1 = [2, 2, 3]
>>> l2 = [2, 2]
>>> l3 = [3, 2]
>>> l4 = [2, 2, 2]
>>> l5 = [2, 5, 2]
>>> is_superset(l1, l2)
True
>>> is_superset(l1, l3)
True
>>> is_superset(l1, l4)
False
>>> is_superset(l1, l5)
False
>>>

答案 3 :(得分:1)

这是一个效率低下的解决方案,用于验证子列表中的每个元素,其子列表中的出现次数必须低于或等于超级列表中的出现次数:

def is_superset(l1, l2):
    return all([l1.count(item) >= l2.count(item) for item in l2])