是否有内置的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
答案 0 :(得分:10)
如果没有重复项,或重复项无关紧要(也就是说,如果您的l1
和l3
都是彼此的超集),那么您只需使用集合。但是,如果你希望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])