Antworten:
Sie können den in
Operator verwenden :
if "blah" not in somestring:
continue
TypeError: argument of type 'NoneType' is not iterable
in
Verwendet der Python- Operator für Zeichenfolgen den Rabin-Carp-Algorithmus?
Wenn es sich nur um eine Teilstringsuche handelt, können Sie diese verwenden string.find("substring")
.
Sie haben mit ein wenig vorsichtig sein find
, index
und in
wenn es , wie sie Suchen werden String. Mit anderen Worten:
s = "This be a string"
if s.find("is") == -1:
print("No 'is' here!")
else:
print("Found 'is' in the string.")
Es würde Found 'is' in the string.
ähnlich drucken , if "is" in s:
würde auswerten True
. Dies kann sein oder nicht, was Sie wollen.
if ' is ' in s:
welche False
wie (wahrscheinlich) erwartet zurückkehren wird.
\bis\b
(Wortgrenzen).
' is '
, insbesondere, ob es nicht fängt This is, a comma'
oder nicht 'It is.'
.
s.split(string.punctuation + string.whitespace)
auch nur einmal aufteilen würde. split
ist nicht wie die strip
/ rstrip
/ lstrip
Funktionsfamilie, sondern wird nur aufgeteilt, wenn alle Trennzeichen zusammenhängend in genau dieser Reihenfolge angezeigt werden. Wenn Sie nach Zeichenklassen aufteilen möchten, kehren Sie zu regulären Ausdrücken zurück (an diesem Punkt ist das Suchen r'\bis\b'
ohne Aufteilen der einfachere und schnellere Weg).
'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split()
- Ok, Punkt genommen. Das ist jetzt lächerlich ...
Hat Python eine Zeichenfolge, die eine Teilzeichenfolgenmethode enthält?
Ja, aber Python verfügt über einen Vergleichsoperator, den Sie stattdessen verwenden sollten, da die Sprache ihre Verwendung beabsichtigt und andere Programmierer von Ihnen erwarten, dass Sie ihn verwenden. Das Schlüsselwort lautet in
, das als Vergleichsoperator verwendet wird:
>>> 'foo' in '**foo**'
True
Das Gegenteil (Ergänzung), nach dem die ursprüngliche Frage fragt, ist not in
:
>>> 'foo' not in '**foo**' # returns False
False
Dies ist semantisch dasselbe wie, not 'foo' in '**foo**'
aber es ist viel besser lesbar und in der Sprache explizit als Verbesserung der Lesbarkeit vorgesehen.
__contains__
, find
undindex
Wie versprochen, hier ist die contains
Methode:
str.__contains__('**foo**', 'foo')
kehrt zurück True
. Sie können diese Funktion auch von der Instanz des Superstrings aus aufrufen:
'**foo**'.__contains__('foo')
Aber nicht. Methoden, die mit Unterstrichen beginnen, werden als semantisch privat betrachtet. Der einzige Grund, dies zu verwenden, ist die Erweiterung der in
und not in
-Funktionalität (z. B. bei Unterklassen 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')
und nun:
>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True
Vermeiden Sie außerdem die folgenden Zeichenfolgenmethoden:
>>> '**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
In anderen Sprachen gibt es möglicherweise keine Methoden zum direkten Testen auf Teilzeichenfolgen. Daher müssten Sie diese Arten von Methoden verwenden. Mit Python ist es jedoch wesentlich effizienter, den in
Vergleichsoperator zu verwenden .
Wir können verschiedene Wege vergleichen, um dasselbe Ziel zu erreichen.
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'))),
}
Und jetzt sehen wir, dass die Verwendung in
viel schneller ist als die anderen. Weniger Zeit für eine gleichwertige Operation ist besser:
>>> 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
und str.find
? Wie sonst würden Sie vorschlagen, dass jemand den Index eines Teilstrings findet, anstatt nur, ob er existiert oder nicht? (oder s.find(ss) != -1
ss in s
re
Moduls besser angegangen werden kann . Ich habe noch keine Verwendung für str.index gefunden oder finde mich in einem Code, den ich noch geschrieben habe.
str.count
von ( string.count(something) != 0
). Schauder
operator
Modulversion ?
in_
oben - aber mit einem Stackframe um es herum, also ist es langsamer als das: github.com/python/cpython/blob/3.7/Lib/operator.py#L153
if needle in haystack:
ist die normale Verwendung, wie @Michael sagt - sie basiert auf dem in
Operator, ist lesbarer und schneller als ein Methodenaufruf.
Wenn Sie wirklich eine Methode anstelle eines Operators benötigen (z. B. um etwas Seltsames key=
für eine sehr eigenartige Art zu tun ...?), Wäre dies der Fall 'haystack'.__contains__
. Aber da dein Beispiel für die Verwendung in einem ist if
, meinst du wohl nicht wirklich, was du sagst ;-). Es ist keine gute Form (weder lesbar noch effizient), spezielle Methoden direkt zu verwenden - sie sollen stattdessen über die Operatoren und integrierten Funktionen verwendet werden, die an sie delegieren.
in
Python-Zeichenfolgen und -ListenHier einige nützliche Beispiele, die für die in
Methode sprechen :
"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]
Vorbehalt. Listen sind iterable und die in
Methode wirkt auf iterables, nicht nur auf Strings.
["bar", "foo", "foobar"] in "foof"
?
Wenn Sie zufrieden sind, "blah" in somestring
aber möchten, dass es sich um einen Funktions- / Methodenaufruf handelt, können Sie dies wahrscheinlich tun
import operator
if not operator.contains(somestring, "blah"):
continue
Alle Operatoren in Python befinden sich mehr oder weniger im Operatormodul einschließlich in
.
Anscheinend gibt es nichts Vergleichbares für den vektorweisen Vergleich. Ein naheliegender Python-Weg wäre:
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
nicht mit Listen verwendet werden sollte, da es einen linearen Scan der Elemente durchführt und im Vergleich langsam ist. Verwenden Sie stattdessen einen Satz, insbesondere wenn Mitgliedschaftstests wiederholt durchgeführt werden sollen.
Sie können verwenden y.count()
.
Es wird der ganzzahlige Wert zurückgegeben, wie oft eine Unterzeichenfolge in einer Zeichenfolge angezeigt wird.
Zum Beispiel:
string.count("bah") >> 0
string.count("Hello") >> 1
Hier ist deine Antwort:
if "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
Um zu überprüfen, ob es falsch ist:
if not "insert_char_or_string_here" in "insert_string_to_search_here":
#DOSTUFF
ODER:
if "insert_char_or_string_here" not in "insert_string_to_search_here":
#DOSTUFF
__contains__(self, item)
,__iter__(self)
und__getitem__(self, key)
in dieser Reihenfolge , ob ein Element liegt enthält in einem bestimmten zu bestimmen. Implementieren Sie mindestens eine dieser Methoden, umin
sie Ihrem benutzerdefinierten Typ zur Verfügung zu stellen.