如何检查以下所有项目是否都在列表中?


114

我发现存在一个有关的问题,即如何查找列表中是否至少有一项:如何检查列表中
是否有以下一项?

但是,找到列表中是否存在所有项的最佳方式是什么?

搜索文档后,我发现此解决方案:

>>> l = ['a', 'b', 'c']
>>> set(['a', 'b']) <= set(l)
True
>>> set(['a', 'x']) <= set(l)
False

其他解决方案是这样的:

>>> l = ['a', 'b', 'c']
>>> all(x in l for x in ['a', 'b'])
True
>>> all(x in l for x in ['a', 'x'])
False

但是在这里您必须进行更多的键入。

还有其他解决方案吗?


5
这有什么错set(smaller) <= set(larger)
eumiro

1
我认为您使用“ all”的第二个解决方案对我来说看起来很好,很Python。
Jiho Noh

Answers:


157

<=Python 这样的运算符通常不会被覆盖以表示与“小于或等于”明显不同的东西。对于标准库来说,这样做是不寻常的-对我来说,它听起来像是旧版API。

使用等效的且更明确命名的方法set.issubset。注意,您不需要将参数转换为集合;如有需要,它将为您完成。

set(['a', 'b']).issubset(['a', 'b', 'c'])

2
不知道您可以直接将列表作为issubset的参数传递...不错!
tsimbalar 2010年

1
虽然我同意这种观点,但我对同一件事的想法<=issubset含义还是很满意的。你为什么不喜欢它?
柯克·斯特拉瑟

2
@Just:主要是因为在没有<=在文档中查找它或对集合论的含义有先验知识的情况下,集合的意义并不明显,而每个人都issubset自动知道含义。
格伦·梅纳德

2
您知道(非正确)子集的数学运算符吗?它基本上看起来很像是一个舍入的<=;)
dom0

喜欢这个解决方案。有没有一种方法来获取索引位置或列表值而不是布尔值(True:False)?
Vlad Gulin

62

我可能会set以以下方式使用:

set(l).issuperset(set(['a','b'])) 

或反过来:

set(['a','b']).issubset(set(l)) 

我觉得它更具可读性,但可能会过分杀人。集合对于计算集合之间的并集/交叉点/差异特别有用,但是在这种情况下,它可能不是最佳选择。


其实MySet.issubset(MyOtherSet)MySet <= MyOtherSet都是一样的。
炒锅2010年

1
@wok:哦,我不知道,但是我认为<=语法有点令人困惑,因为类似的语法可以用于列表,但含义却大不相同。
tsimbalar 2010年

3
如果您还记得包含在任何一组集合上定义了部分顺序,那真的不是那么令人困惑。实际上,<=它对序列的含义有些混乱:人们可能希望它的意思是“是子序列”而不是字典顺序。
aaronasterling

1
@aaronasterling:嗯,当我键入代码时,我个人不太想“偏序” :-),但我同意这样的事实,即使用<=序列也感觉有些奇怪,……
tsimbalar 2010年

3
我跑进一个小疑难杂症在这里,我想提一提:如果您使用此方法,您正在转换您的列表,以套,这意味着没有重复。set(['a','a']).issubset(['a'])返回True
Orangestar

11

我喜欢这两个,因为它们看起来最合乎逻辑,后者更短并且可能最快(此处使用set文字语法显示,该文字语法已 反向移植到Python 2.7):

all(x in {'a', 'b', 'c'} for x in ['a', 'b'])
#   or
{'a', 'b'}.issubset({'a', 'b', 'c'})

使用timeit()进行测量时,“所有”解决方案是最快的。这应该是公认的答案。
Attersson

3

如果您的列表包含这样的重复项,该怎么办:

v1 = ['s', 'h', 'e', 'e', 'p']
v2 = ['s', 's', 'h']

集不包含重复项。因此,以下行返回True。

set(v2).issubset(v1)

要计算重复项,可以使用以下代码:

v1 = sorted(v1)
v2 = sorted(v2)


def is_subseq(v2, v1):
    """Check whether v2 is a subsequence of v1."""
    it = iter(v1)
    return all(c in it for c in v2) 

因此,以下行返回False。

is_subseq(v2, v1)

1

这就是我在网上搜索的内容,但不幸的是,我在python解释器上进行实验时发现不是在线的。

>>> case  = "caseCamel"
>>> label = "Case Camel"
>>> list  = ["apple", "banana"]
>>>
>>> (case or label) in list
False
>>> list = ["apple", "caseCamel"]
>>> (case or label) in list
True
>>> (case and label) in list
False
>>> list = ["case", "caseCamel", "Case Camel"]
>>> (case and label) in list
True
>>>

如果您有一个完整的变量列表 sublist variable

>>>
>>> list  = ["case", "caseCamel", "Case Camel"]
>>> label = "Case Camel"
>>> case  = "caseCamel"
>>>
>>> sublist = ["unique banana", "very unique banana"]
>>>
>>> # example for if any (at least one) item contained in superset (or statement)
...
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
False
>>>
>>> sublist[0] = label
>>>
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
True
>>>
>>> # example for whether a subset (all items) contained in superset (and statement)
...
>>> # a bit of demorgan's law
...
>>> next((False for item in sublist if item not in list), True)
False
>>>
>>> sublist[1] = case
>>>
>>> next((False for item in sublist if item not in list), True)
True
>>>
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
True
>>>
>>>

0

如何使用lambda表达式执行此操作的示例如下:

issublist = lambda x, y: 0 in [_ in x for _ in y]

1
请添加评论以解释/详细说明您的答案
莎拉德(Sharad),

0

不是OP的情况,但是-对于任何想要在字典中声明交集 并由于不良谷歌搜索而最终到这里的人(例如我)-您需要与dict.items

>>> a = {'key': 'value'}
>>> b = {'key': 'value', 'extra_key': 'extra_value'}
>>> all(item in a.items() for item in b.items())
True
>>> all(item in b.items() for item in a.items())
False

那是因为dict.items返回键/值对的元组,就像Python中的任何对象一样,它们可以互换地比较

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.