Python:看看一组是否完全包含另一组?


81

有没有一种快速的方法来检查一组是否完全包含另一组?

就像是:

>>>[1, 2, 3].containsAll([2, 1])
True

>>>[1, 2, 3].containsAll([3, 5, 9])
False

Answers:


124

这些是列表,但是如果您的意思是集合,则可以使用issubset方法。

>>> s = set([1,2,3])
>>> t = set([1,2])
>>> t.issubset(s)
True
>>> s.issuperset(t)
True

对于列表,将无法比检查每个元素做得更好。


3
当我看到这个答案时,我会感到一种奇怪的似曾相识的感觉
Christophe Roussy

您必须意识到issubset()not的语义contains()
Wikier '19

37

为了完整起见:这等效于issubset(尽管可以说不太明确/可读):

>>> set([1,2,3]) >= set([2,1])
True
>>> set([1,2,3]) >= set([3,5,9])
False

问题是a = set([])和b = set(['a','b'])然后a.issubset(b)是True
darkman

4

一个选项保持不变-减法:

>>> {1, 2} - {1, 2, 3}
set([])
>>> {1, 2, 3} - {1, 2}
set([3])

基本上,您检查第一个列表中的哪些元素不在第二个列表中。

我发现它非常方便,因为您可以显示缺少的值:

>>> def check_contains(a, b):
...     diff = a - b
...     if not diff:
...         # All elements from a are present in b
...         return True
...     print('Some elements are missing: {}'.format(diff))
...     return False
...
>>> check_contains({1, 2}, {1, 2, 3})
True
>>> check_contains({1, 2, 3}, {1, 2})
Some elements are missing: set([3])
False

3

您可以使用set.issubset()set.issuperset()(或基于其运算符的对应项:<=>=)。请注意,这些方法将接受任何iterable作为参数,而不仅仅是一个set:

>>> {1, 2}.issubset([1, 2, 3])
True
>>> {1, 2, 3}.issuperset([1, 2])
True

但是,如果使用运算符,则必须设置两个参数:

>>> {1, 2} <= {1, 2, 3}
True
>>> {1, 2, 3} >= {1, 2}
True

3

如果您怀疑一个集合是另一个集合的子集,并且将这两个集合相交,则如果它是一个子集,则结果等于自身。

a = [2,1,3,3]
b = [5,4,3,2,1]
set(a).intersection(set(b)) == set(a)
>>True

1
A = set(a)B = set(b)为理智。然后,该比较有效地简化为len(A.intersection(B)) == len(A)。也就是说,本身需要的集相比较逐元素; 仅需要比较这些集合的基数。但是,即使是这种优化也可能不足以使该方法更可取。将大大更具可读性高效issubset()<=方法几乎肯定是每个人都想要的。
塞西尔·库里

@CecilCurry是的-我错误地使用了“基数”一词,因为它是长度的度量。我更新了措辞。您的优化是基于我的错误的错误。不是优化。与“> =”的重载含义相比,“ intersection()”的字面措词读起来更明确,并且指出“ issubset()”更易于阅读,这是显而易见的消除,因为它是最受欢迎的答案。除了重复别人的答案外,还可以自由地提出创新的解决方案。
乔丹·斯特凡内利

1
>>> set([1,2,3]).issuperset(set([2,1]))
True 
>>>    
>>> set([1,2,3]).issuperset(set([3,5,9]))
False

3
考虑适当地格式化您的答案并添加一些说明。
山姆

0

如果主列表未完全包含子列表,则函数下方返回0,如果完全包含子列表,则返回1。

def islistsubset(sublist,mainlist):
     for item in sublist:
             if item in mainlist:
                     contains = 1
             else:
                     contains = 0
                     break;
     return contains

1
这是O(n ^ 2),同时使用设置操作,因为某些现有答案中的操作要快得多。这也可以写得很简单any(item in mainlist for item in sublist)
Iguananaut

同意事实上我也可以写def islistsubset(sublist,mainlist):对于子列表中的项目,contains = 1:如果在主列表中的项目:Continue else:contains = 0 break; 返回包含所以每次通话只有2个任务
博宾Motti托马斯

@BobinMottiThomas您可以直接返回True或False,而无需创建任何临时变量。对于list_a中的项目:如果项目不在list_b中:返回False返回True
Jordan Stefanelli
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.