Czy Python ma metodę string 'contains'substring?

odpowiedzi na to pytanie są wysiłkiem społeczności. Edytuj istniejące odpowiedzi, aby poprawić ten post. Obecnie nie przyjmuje nowych odpowiedzi ani interakcji.

Szukam metody string.contains lub string.indexof w Python.

Chcę zrobić:

if not somestring.contains("blah"):
   continue
Author: Peter Mortensen, 2010-08-09

10 answers

Możesz użyć in operator :

if "blah" not in somestring: 
    continue
 6798
Author: Michael Mrozek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-11 23:30:17

Jeśli jest to tylko szukanie fragmentu tekstu, możesz użyć string.find("substring").

Musisz być trochę ostrożny z find, index, oraz in chociaż, ponieważ są to wyszukiwania podciągów. Innymi słowy, to:

s = "This be a string"
if s.find("is") == -1:
    print("No 'is' here!")
else:
    print("Found 'is' in the string.")

Wydrukuje Found 'is' in the string. podobnie, if "is" in s: oceni na True. To może być to, czego chcesz.

 714
Author: eldarerathis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-18 15:35:15

Czy Python ma metodę string contains substring?

99% przypadki użycia zostaną opisane za pomocą słowa kluczowego, in, które zwraca True lub False:

'substring' in any_string

Aby uzyskać indeks, użyj str.find (która zwraca -1 po niepowodzeniu i ma opcjonalne argumenty pozycyjne):

start = 0
stop = len(any_string)
any_string.find('substring', start, stop)

Lub str.index (podobnie jak find ale podnosi ValueError w przypadku awarii):

start = 100 
end = 1000
any_string.index('substring', start, end)

Wyjaśnienie

Użyj operatora porównania in ponieważ

  1. język zamierza używać, a
  2. inni programiści Pythona będą oczekiwać, że go użyjesz.
>>> 'foo' in '**foo**'
True

Przeciwieństwem (dopełnieniem), o które zadano pierwotne pytanie, jest not in:

>>> 'foo' not in '**foo**' # returns False
False

Jest to semantycznie to samo co not 'foo' in '**foo**', ale jest o wiele bardziej czytelne i wyraźnie przewidziane w języku jako poprawa czytelności.

Unikaj używania __contains__

Metoda "contains" implementuje zachowanie dla in. To przykład,

str.__contains__('**foo**', 'foo')

Zwraca True. Można również wywołać tę funkcję z instancji superstringu:

'**foo**'.__contains__('foo')

Ale nie. Metody zaczynające się od podkreślenia są uważane za semantycznie Niepubliczne. Jedynym powodem do tego jest implementacja lub rozszerzenie funkcjonalności in i not in (np. jeśli podklasowanie str):

class NoisyString(str):
    def __contains__(self, other):
        print(f'testing if "{other}" in "{self}"')
        return super(NoisyString, self).__contains__(other)

ns = NoisyString('a string with a substring inside')

A teraz:

>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True

Nie używaj find i index do testowania NA "zawiera"

Nie używaj następujących metod łańcuchowych, aby test dla "zawiera":

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

Inne języki mogą nie mieć metod do bezpośredniego testowania podciągów, więc będziesz musiał używać tego typu metod, ale w Pythonie o wiele bardziej wydajne jest użycie operatora porównania in.

Również, nie są to zamienniki drop-in dla in. Być może będziesz musiał obsłużyć wyjątek lub przypadki -1, a jeśli zwrócą 0 (ponieważ znaleźli podłańcuch na początku), interpretacja logiczna to False zamiast True.

Jeśli naprawdę masz na myśli to powiedz.

Porównania wydajności

Możemy porównać różne sposoby osiągnięcia tego samego celu.
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'))),
}

I teraz widzimy, że używanie in jest znacznie szybsze niż inne. Mniej czasu na wykonanie równoważnej operacji jest lepsze:

>>> 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}
 259
Author: Aaron Hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-21 13:41:21

if needle in haystack: jest normalnym użytkowaniem ,jak mówi @ Michael-polega na in operator, bardziej czytelny i szybszy niż wywołanie metody.

Jeśli naprawdę potrzebujesz metody zamiast operatora (np. zrobić jakiś dziwny key= dla bardzo osobliwego rodzaju...?), czyli 'haystack'.__contains__. Ale ponieważ twój przykład jest do użycia w if, chyba nie masz na myśli tego, co mówisz; -). Nie jest dobrą formą (ani czytelną, ani efektywną) bezpośredniego stosowania specjalnych metod - są one przeznaczone do, zamiast tego, poprzez operatorów i builtins, które delegują do nich.

 182
Author: Alex Martelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-20 04:07:17

in ciągi Pythona i listy

Oto kilka przydatnych przykładów, które mówią same za siebie o metodzie 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]

Zastrzeżenie. Listy są iterablami, a Metoda in działa na iterablach, a nie tylko na łańcuchach.

 66
Author: firelynx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Jeśli jesteś zadowolony z "blah" in somestring, ale chcesz, aby było to wywołanie funkcji/metody, prawdopodobnie możesz to zrobić

import operator

if not operator.contains(somestring, "blah"):
    continue

Wszystkie operatory w Pythonie można mniej więcej znaleźć w module operator łącznie z in.

 43
Author: Jeffrey04,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-09 12:36:08

Więc najwyraźniej nie ma nic podobnego do porównania wektorowego. Oczywistym Pythonowym sposobem na to jest:

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
 41
Author: Ufos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-06 08:49:22

Możesz użyć y.count().

Zwróci liczbę całkowitą liczby wystąpień podciągu w łańcuchu.

Na przykład:

string.count("bah") >> 0
string.count("Hello") >> 1
 26
Author: Brandon Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-26 07:44:54

Oto Twoja odpowiedź:

if "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

Do sprawdzenia czy jest false:

if not "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

Lub:

if "insert_char_or_string_here" not in "insert_string_to_search_here":
    #DOSTUFF
 21
Author: ytpillai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 14:18:35

Możesz użyć wyrażeń regularnych, aby uzyskać wystąpienia:

>>> import re
>>> print(re.findall(r'( |t)', to_search_in)) # searches for t or space
['t', ' ', 't', ' ', ' ']
 9
Author: Muskovets,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-17 05:07:46