Python, ключевое слово "a in b", как насчет нескольких a?
Мои приключения в Python продолжаются, и мои любимые книги снова молчат. Python предлагает встроенный способ проверить, находится ли переменная внутри итерабельного объекта, используя ключевое слово "in":
if "a" in "abrakadabra" :
print "it is definitely here"
Но можно ли проверить, включено ли в список более одного элемента (любой)?
В настоящее время я использую синтаксис ниже, но он длинный:
if "// @in " in sTxt or "// @out " in sTxt or "// @ret " in sTxt or <10 more>
print "found."
Конечно, регулярные выражения могут помочь, но с помощью регулярных выражений будет много многословного кода и будет
не так ясно, как "a in b". Есть ли еще какие-нибудь питонические пути?
Ответы
Ответ 1
alternatives = ("// @in ", "// @out ", "// @ret ")
if any(a in sTxT for a in alternatives):
print "found"
if all(a in sTxT for a in alternatives):
print "found all"
any()
и all()
берет iterable и проверяет, действительно ли они/все они оцениваются с истинным значением. Объедините это с выражением генератора, и вы можете проверить несколько элементов.
Ответ 2
any(snippet in text_body for snippet in ("hi", "foo", "bar", "spam"))
Ответ 3
Если вы тестируете множество строк для одних и тех же слов, может быть быстрее скомпилировать их как регулярное выражение. например:
import re
words = ["// @in ", "// @out ", "// @ret "] + ["// @test%s " % i for i in range(10)]
my_regex = re.compile("|".join(map(re.escape, words)))
for line in lines_to_search:
if my_regex.search(line): print "Found match"
Некоторые быстрые сроки показывают, что это обычно быстрее, чем подход any(word in theString for word in words)
. Я тестировал оба подхода с разным текстом (короткий/длинный с/без совпадений). Вот результаты:
{ No keywords } | {contain Keywords }
short long short long
regex : 0.214 27.214 0.147 0.149
any in : 0.579 81.341 0.295 0.300
Если производительность не имеет значения, подход any()
более читабельен.
Ответ 4
Если вы хотите любой чек, вы должны использовать это:
inthere = False
checks = ('a', 'b')
for check in checks:
if check in 'abrakadabra':
inthere = True
break
Если вы хотите все проверить, вы можете использовать это:
inthere = True
checks = ('a', 'b')
for check in checks:
if check not in 'abrakadabra':
inthere = False
break
EDIT: Не знаю, больше pythonic any()
. Вероятно, лучше использовать это на python.
EDIT2: Добавлены инструкции break и исправлены все случаи.
Ответ 5
Вы также можете использовать установить методы и операторы:
not alternatives.isdisjoint(sTxt) # for "any"
(alternatives & sTxt) != set() # Again, the intersection is nonempty
alternatives <= sTxt # for "all"
Я думаю, что их легче читать, чем использовать все или все, но вам нужно преобразовать свои коллекции в группы. Поскольку пересечение и сдерживание - это то, о чем вы заботитесь, вы можете подумать о том, чтобы сделать их наборы в первую очередь.
Ответ 6
В синтаксисе нет встроенного способа сделать это. Однако вы можете использовать функцию "any", чтобы упростить ее, как показали @MizardX и @Benjamin Peterson.