Ich habe eine Liste von Tupeln in Python , und ich habe eine Bedingung, wo ich den Zweig NUR nehmen möchte, wenn der Tupel nicht in der Liste ist (wenn er in der Liste ist, dann nicht) will den if Zweig nehmen)
if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList:
# Do Something
Das funktioniert bei mir allerdings nicht wirklich. Was habe ich falsch gemacht?
Der Fehler befindet sich wahrscheinlich an einer anderen Stelle in Ihrem Code, da er problemlos funktionieren sollte:
>>> 3 not in [2, 3, 4]
False
>>> 3 not in [4, 5, 6]
True
Oder mit Tupeln:
>>> (2, 3) not in [(2, 3), (5, 6), (9, 1)]
False
>>> (2, 3) not in [(2, 7), (7, 3), "hi"]
True
Wie überprüfe ich, ob sich etwas in einer Liste in Python befindet (nicht)?
Die billigste und am besten lesbare Lösung ist die Verwendung des Operators in
(oder in Ihrem speziellen Fall not in
). Wie in der Dokumentation erwähnt,
Die Operatoren
in
undnot in
testen auf Mitgliedschaft.x in s
ergibtTrue
, wennx
Mitglied vons
ist, andernfallsFalse
.x not in s
gibt die Negation vonx in s
zurück.
Zusätzlich,
Der Operator
not in
hat den umgekehrten wahren Wert vonin
.
y not in x
ist logisch dasselbe 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 in der RHS eine __contains__()
-Methode definiert, wird sie von in
intern aufgerufen, wie im letzten Absatz des Abschnitts Comparisons der Dokumentation angegeben.
...
in
undnot in
werden von Typen unterstützt, die iterierbar sind oder die Methode__contains__()
implementieren. Zum Beispiel könnten (sollten) Sie dies tun:
[3, 2, 1].__contains__(1)
# True
in
schließt kurz. Wenn sich Ihr Element also am Anfang der Liste befindet, wird 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, haben Sie folgende Möglichkeiten:
list.index
kann verwendet werden, um den Index eines Elements abzurufen. Wenn dieses Element nicht vorhanden ist, wird ein ValueError
ausgelöst.list.count
kann verwendet werden, wenn Sie die Vorkommen zählen möchten.set
s in Betracht gezogen?Stellen Sie sich folgende Fragen:
hash
anrufen?Wenn Sie diese Fragen mit "Ja" beantwortet haben, sollten Sie stattdessen set
verwenden. Ein in
-Mitgliedschaftstest für list
s ist O(n) zeitlich komplex. Dies bedeutet, dass python einen linearen Scan Ihrer Liste durchführen muss, wobei jedes Element besucht und mit dem Suchbegriff verglichen wird. Wenn Sie dies wiederholt ausführen oder wenn die Listen groß sind, verursacht dieser Vorgang einen Mehraufwand.
set
-Objekte hingegen haben ihre Werte für die ständige Überprüfung der Zeitzugehörigkeit. Die Prü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 sich das Element, nach dem Sie suchen/das Sie nicht suchen, am Ende Ihrer Liste befindet, hat python die Liste bis zum Ende durchsucht. 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, es müssten entweder unveränderliche Typen oder Objekte sein, die __hash__
implementieren.