Відповіді:
Ви можете скористатися inоператором :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
inоператор Python для алгоритму Rabin-Carp?
Якщо це просто пошук підрядка, який ви можете використовувати string.find("substring").
Ви повинні бути трохи обережним з find, indexі inхоча, як вони пошук подстрок. Іншими словами, це:
s = "This be a string"
if s.find("is") == -1:
print("No 'is' here!")
else:
print("Found 'is' in the string.")
Було б надруковано Found 'is' in the string.Аналогічно, if "is" in s:оцінювали б True. Це може бути або не бути тим, що ви хочете.
if ' is ' in s:що повернеться так, Falseяк це (мабуть) очікується.
\bis\b(кордони слова).
' is ', зокрема, воно не сприймає This is, a comma'або 'It is.'.
s.split(string.punctuation + string.whitespace)розділиться навіть один раз; splitне схоже на сімейство функцій strip/ rstrip/ lstrip, воно розбивається лише тоді, коли воно бачить усі символи-роздільники безперервно в такому точному порядку. Якщо ви хочете розділити на класи символів, ви повернетесь до регулярних виразів (в цей момент пошук r'\bis\b'без розщеплення - простіший і швидший шлях).
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split()- добре, точка взята. Це зараз смішно ...
Чи є в Python рядок містить метод підрядки?
Так, але Python має оператор порівняння, який ви повинні використовувати замість цього, оскільки мова має намір використовувати його, а інші програмісти очікують, що ви будете ним користуватися. Це ключове слово in, яке використовується в якості оператора порівняння:
>>> 'foo' in '**foo**'
True
Протилежністю (доповненням), яку задає оригінальне запитання, є not in:
>>> 'foo' not in '**foo**' # returns False
False
Це семантично те саме, що є, not 'foo' in '**foo**'але набагато читабельніше і чітко передбачено мовою як поліпшення читабельності.
__contains__, findіindexЯк було обіцяно, ось такий containsметод:
str.__contains__('**foo**', 'foo')
повертає True. Ви також можете викликати цю функцію з екземпляра суперструни:
'**foo**'.__contains__('foo')
Але не варто. Методи, які починаються з підкреслення, вважаються семантично приватними. Єдина причина використовувати це при розширенні inта not inфункціональності (наприклад, якщо підкласифікація str):
class NoisyString(str):
def __contains__(self, other):
print('testing if "{0}" in "{1}"'.format(other, self))
return super(NoisyString, self).__contains__(other)
ns = NoisyString('a string with a substring inside')
і зараз:
>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True
Також уникайте наступних рядкових методів:
>>> '**foo**'.index('foo')
2
>>> '**foo**'.find('foo')
2
>>> '**oo**'.find('foo')
-1
>>> '**oo**'.index('foo')
Traceback (most recent call last):
File "<pyshell#40>", line 1, in <module>
'**oo**'.index('foo')
ValueError: substring not found
Інші мови можуть не мати методів прямого тестування на підрядки, і тому вам доведеться використовувати ці типи методів, але з Python набагато ефективніше використовувати inоператор порівняння.
Ми можемо порівняти різні способи досягнення однієї і тієї ж мети.
import timeit
def in_(s, other):
return other in s
def contains(s, other):
return s.__contains__(other)
def find(s, other):
return s.find(other) != -1
def index(s, other):
try:
s.index(other)
except ValueError:
return False
else:
return True
perf_dict = {
'in:True': min(timeit.repeat(lambda: in_('superstring', 'str'))),
'in:False': min(timeit.repeat(lambda: in_('superstring', 'not'))),
'__contains__:True': min(timeit.repeat(lambda: contains('superstring', 'str'))),
'__contains__:False': min(timeit.repeat(lambda: contains('superstring', 'not'))),
'find:True': min(timeit.repeat(lambda: find('superstring', 'str'))),
'find:False': min(timeit.repeat(lambda: find('superstring', 'not'))),
'index:True': min(timeit.repeat(lambda: index('superstring', 'str'))),
'index:False': min(timeit.repeat(lambda: index('superstring', 'not'))),
}
І тепер ми бачимо, що використання inнабагато швидше, ніж інші. Менше часу на еквівалентну операцію краще:
>>> perf_dict
{'in:True': 0.16450627865128808,
'in:False': 0.1609668098178645,
'__contains__:True': 0.24355481654697542,
'__contains__:False': 0.24382793854783813,
'find:True': 0.3067379407923454,
'find:False': 0.29860888058124146,
'index:True': 0.29647137792585454,
'index:False': 0.5502287584545229}
str.indexі str.find? Як ще ви запропонували б комусь знайти індекс підрядки замість того, чи існує він чи ні? (чи ти мав на увазі уникати використання їх замість вмісту - тому не використовуй s.find(ss) != -1замість ss in s?)
reмодуля. Я ще не знайшов використання str.index або str.find у будь-якому коді, який я ще написав.
str.countтакож ( string.count(something) != 0). здригаються
operatorверсія модуля ?
in_вище, але зі складовою рамкою навколо нього, тож це повільніше, ніж це: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
if needle in haystack:це нормальне використання, як каже @Michael - воно покладається на inоператора, читабельніше та швидше, ніж виклик методу.
Якщо вам справді потрібен метод замість оператора (наприклад, зробити якийсь дивний key=для дуже своєрідного роду ...?), Це було б 'haystack'.__contains__. Але оскільки ваш приклад використовується для використання в if, я думаю, ви насправді не маєте на увазі те, що ви говорите ;-). Недоцільно (ні читати, ні ефективно) використовувати спеціальні методи безпосередньо - вони призначені для використання натомість через оператори та вбудовані модулі, які делегують їм.
in Рядки та списки PythonОсь кілька корисних прикладів, які говорять самі про inметод:
"foo" in "foobar"
True
"foo" in "Foobar"
False
"foo" in "Foobar".lower()
True
"foo".capitalize() in "Foobar"
True
"foo" in ["bar", "foo", "foobar"]
True
"foo" in ["fo", "o", "foobar"]
False
["foo" in a for a in ["fo", "o", "foobar"]]
[False, False, True]
Caveat. Списки є ітерабельними, а inметод діє на ітерабелі, а не лише на рядки.
["bar", "foo", "foobar"] in "foof":?
Якщо ви задоволені, "blah" in somestringале хочете, щоб це був виклик функції / методу, ви, ймовірно, можете це зробити
import operator
if not operator.contains(somestring, "blah"):
continue
Усі оператори в Python можуть бути більш-менш знайдені в операторському модулі, включаючи in.
Тому, мабуть, немає нічого подібного для векторного порівняння. Очевидним способом Python це було б:
names = ['bob', 'john', 'mike']
any(st in 'bob and john' for st in names)
>> True
any(st in 'mary and jane' for st in names)
>> False
inзастосовувати зі списками, оскільки це робить лінійне сканування елементів і порівняно повільне. Замість цього використовуйте набір, особливо якщо тести на членство потрібно робити неодноразово.
Можна використовувати y.count().
Він поверне ціле значення кількості разів, коли в рядку з'являється підряд.
Наприклад:
string.count("bah") >> 0
string.count("Hello") >> 1
Ось ваша відповідь:
if "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
Щоб перевірити, чи неправдиво:
if not "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
АБО:
if "insert_char_or_string_here" not in "insert_string_to_search_here":
#DOSTUFF
__contains__(self, item),__iter__(self)і__getitem__(self, key)в цьому порядку визначати, чи лежить елемент у заданому вмісті. Реалізуйте принаймні один із цих методів, щоб зробитиinдоступними для вашого власного типу.