Ответы:
Вы можете использовать in
оператор :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
in
оператор Python алгоритм Рабина-Карпа?
Если это просто поиск по подстроке, вы можете использовать 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]
Предостережение. Списки являются итеративными, а 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
доступным для вашего пользовательского типа.