У Python есть более чистый способ выразить "если x содержит a | b | c | d..."?

Pythonic способ проверить, является ли строка x подстрокой y:

if x in y:

Поиск, если x эквивалентен a, b, c, d, e, f или g также Pythonic:

if x in [a,b,c,d,e,f,g]:

Но, если какая-либо строка x содержит либо a, b, c, d, e, f, либо g кажется неуклюжим:

if a in x or b in x or c in x or d in x or e in x or f in x or g in x

Существует ли более Pythonic метод проверки, содержит ли строка x элемент списка?

Я знаю, что это тривиально написать это сам, используя цикл или используя регулярное выражение:

re.search('(dog|cat|bird|mouse|elephant|pig|cow)', x)

но мне было интересно, есть ли более чистый способ, который не связан с регулярным выражением.

Ответ 1

Подход Pythonic должен был бы использовать any():

if any(s in x for s in (a,b,c,d,e,f,g)):

Из связанной документации:

any (итерацию)

Возвращаем значение True, если какой-либо элемент итерабельности является истинным. Если итерабельность пуста, верните False. Эквивалентно:

def any(iterable):
    for element in iterable:
        if element:
            return True
    return False

Также обратите внимание, что я использовал кортеж вместо списка здесь. Если ваши значения a - g предварительно определены, то кортеж действительно будет предпочтительнее. Смотрите: Являются ли кортежи более эффективными, чем списки в Python?

Ответ 2

if any(q in x for q in [a,b,c,d,e,f,g]):

Я думаю, что это как короткий и Pythonic, как вы можете его получить.

Ответ 3

Немного поздно для вечеринки, но

not frozenset(x).isdisjoint(frozenset(y))

будет работать и может быть быстрее (алгоритмически, но, возможно, не для более мелких тестовых случаев).

Ответ 4

без использования any, а просто max

def is_in(symbol, lst):
    return max([symbol in x for x in lst]) 

print is_in('a',['ae','br','tl'])
print is_in('c',['ae','br','tl'])

дает

>>> 
True
False