Как проверить, есть ли все перечисленные ниже элементы в списке? - PullRequest
94 голосов
/ 14 октября 2010

Я обнаружил, что есть связанный вопрос о том, как найти, если хотя бы один элемент существует в списке:
Как проверить, есть ли один из следующих элементов в списке?

Но каков наилучший и питонный способ узнать, есть ли все элементы в списке?

При поиске в документах я нашел это решение:

>>> 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

Но здесь вы должны больше печатать.

Есть ли другие решения?

Ответы [ 6 ]

115 голосов
/ 14 октября 2010

Такие операторы, как <= в Python, обычно не переопределяются, чтобы означать что-то значительно отличающееся от «меньше или равно».Это необычно для стандартной библиотеки, так как она пахнет для меня устаревшим API.

Используйте эквивалентный и более четко названный метод set.issubset.Обратите внимание, что вам не нужно преобразовывать аргумент в набор;он сделает это за вас, если потребуется.

set(['a', 'b']).issubset(['a', 'b', 'c'])
59 голосов
/ 14 октября 2010

Я бы, вероятно, использовал set следующим образом:

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

или наоборот:

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

Я нахожу это немногоболее читабельным, но это может быть чрезмерным.Наборы особенно полезны для вычисления объединения / пересечения / различий между коллекциями, но это может быть не лучшим вариантом в этой ситуации ...

9 голосов
/ 14 октября 2010

Мне нравятся эти два, потому что они кажутся наиболее логичными, последний является более коротким и, вероятно, самым быстрым (показано здесь с использованием буквенного синтаксиса set, который был перенесен *1003* в Python 2.7):

all(x in {'a', 'b', 'c'} for x in ['a', 'b'])
#   or
{'a', 'b'}.issubset({'a', 'b', 'c'})
2 голосов
/ 05 августа 2017

Что если в ваших списках есть дубликаты вроде этого:

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)
0 голосов
/ 29 января 2019

Пример того, как сделать это с помощью лямбда-выражения:

issublist = lambda x, y: 0 in [_ in x for _ in y]
0 голосов
/ 29 января 2019

Это было то, что я искал в сети, но, к сожалению, нашел не в сети, а во время экспериментов с интерпретатором 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
>>>
>>>
...