Ich habe eine Liste von Tupeln in Python und eine Bedingung, unter der ich den Zweig NUR nehmen möchte, wenn das Tupel nicht in der Liste enthalten ist (wenn es in der Liste enthalten ist, möchte ich den Zweig if nicht verwenden).
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?
3 -1 > 0 and (4-1 , 5) not in []
⤇True
der Fehler daher keine Priorität für den Operator hat.myList.count((curr_x, curr_y))
, wenn(curr_x, curr_y)
nicht inmyList
, wird das Ergebnis sein0
Antworten:
Der Fehler befindet sich wahrscheinlich an einer anderen Stelle in Ihrem Code, da er einwandfrei funktionieren sollte:
Oder mit Tupeln:
quelle
if not ELEMENT in COLLECTION:
A not in B
es auf das reduziert ist,not B.__contains__(A)
was das gleiche ist wie das, was aufnot A in B
das reduziert istnot B.__contains__(A)
.__notcontains__
. Es tut mir leid, dann ist das, was ich gesagt habe, nur Schwachsinn.not
eine höhere Priorität hätte alsin
dies nicht der Fall ist. Betrachten Sie das Ergebnis,ast.dump(ast.parse("not A in B").body[0])
das zu"Expr(value=UnaryOp(op=Not(), operand=Compare(left=Name(id='A', ctx=Load()), ops=[In()], comparators=[Name(id='B', ctx=Load())])))"
Wenn Sienot
eng zu A gruppiert sind, hätte man erwartet, dass das Ergebnis"Expr(value=Compare(left=UnaryOp(op=Not(), operand=Name(id='A', ctx=Load())), ops=[In()], comparators=[Name(id='B', ctx=Load())]))"
das ist, für das analysiert wird"(not A) in B"
.Die billigste und am besten lesbare Lösung ist die Verwendung des
in
Operators (oder in Ihrem speziellen Fallnot in
). Wie in der Dokumentation erwähnt,Zusätzlich,
y not in x
ist logisch das gleiche wienot y in x
.Hier einige Beispiele:
Dies funktioniert auch mit Tupeln, da Tupel hashbar sind (aufgrund der Tatsache, dass sie auch unveränderlich sind):
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
Kurzschlüsse. Wenn sich Ihr Element also am Anfang der Liste befindet, wird esin
schneller ausgewertet: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:
hash
?Wenn Sie diese Fragen mit "Ja" beantwortet haben, sollten Sie
set
stattdessen ein verwenden. Einin
Mitgliedschaftstest fürlist
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 mitin
: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:
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__
.quelle