Wie überprüfe ich, ob etwas in einer Liste in Python (nicht) enthalten ist?
Die billigste und am besten lesbare Lösung ist die Verwendung des in
Operators (oder in Ihrem speziellen Fall not in
). Wie in der Dokumentation erwähnt,
Die Betreiber in
und not in
Test auf Mitgliedschaft. x in s
bewertet,
True
ob x
Mitglied von ists
und False
anderweitig ist. x not in s
gibt die Negation von zurück x in s
.
Zusätzlich,
Der Betreiber not in
hat den umgekehrten wahren Wert von in
.
y not in x
ist logisch das gleiche wie not y in x
.
Hier einige Beispiele:
'a' in [1, 2, 3]
# False
'c' in ['a', 'b', 'c']
# True
'a' not in [1, 2, 3]
# True
'c' not in ['a', 'b', 'c']
# False
Dies funktioniert auch mit Tupeln, da Tupel hashbar sind (aufgrund der Tatsache, dass sie auch unveränderlich sind):
(1, 2) in [(3, 4), (1, 2)]
# True
Wenn das Objekt auf der RHS eine __contains__()
Methode definiert , in
wird es intern aufgerufen, wie im letzten Absatz des Abschnitts " Vergleiche " der Dokumente angegeben.
... in
und not in
werden von Typen unterstützt, die iterierbar sind oder die __contains__()
Methode implementieren
. Zum Beispiel könnten (aber sollten) Sie dies nicht tun:
[3, 2, 1].__contains__(1)
# True
in
Kurzschlüsse. Wenn sich Ihr Element also am Anfang der Liste befindet, wird es in
schneller ausgewertet:
lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst # Expected to take longer time.
68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Wenn Sie mehr als nur prüfen möchten, ob sich ein Element in einer Liste befindet, gibt es folgende Optionen:
list.index
kann verwendet werden, um den Index eines Elements abzurufen. Wenn dieses Element nicht vorhanden ist, ValueError
wird a ausgelöst.
list.count
kann verwendet werden, wenn Sie die Vorkommen zählen möchten.
Das XY-Problem: Haben Sie darüber nachgedacht? set
s ?
Stellen Sie sich folgende Fragen:
- Müssen Sie mehrmals prüfen, ob ein Element in einer Liste enthalten ist?
- Wird diese Prüfung in einer Schleife durchgeführt oder eine Funktion wiederholt aufgerufen?
- Sind die Elemente, die Sie auf Ihrer Liste speichern, hashbar? IOW, können Sie sie anrufen
hash
?
Wenn Sie diese Fragen mit "Ja" beantwortet haben, sollten Sie set
stattdessen ein verwenden. Einin
Mitgliedschaftstest für list
s ist O (n) Zeitkomplexität. Dies bedeutet, dass Python einen linearen Scan Ihrer Liste durchführen muss, jedes Element besucht und es mit dem Suchelement vergleicht. Wenn Sie dies wiederholt tun oder wenn die Listen groß sind, verursacht dieser Vorgang einen Overhead.
set
Objekte hingegen haben ihre Werte für die Überprüfung der Mitgliedschaft in konstanter Zeit gehasht. Die Überprüfung erfolgt auch mit in
:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
Wenn Sie das Pech haben, dass das Element, nach dem Sie suchen / nicht suchen, am Ende Ihrer Liste steht, hat Python die Liste bis zum Ende gescannt. Dies geht aus den folgenden Zeitpunkten hervor:
l = list(range(100001))
s = set(l)
%timeit 100000 in l
%timeit 100000 in s
2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Zur Erinnerung, dies ist eine geeignete Option, solange die Elemente, die Sie speichern und nachschlagen, hashbar sind. IOW müssten entweder unveränderliche Typen oder implementierte Objekte sein __hash__
.
3 -1 > 0 and (4-1 , 5) not in []
⤇True
der Fehler daher keine Priorität für den Operator hat.