[python] Warum gibt "nicht (Wahr) in [Falsch, Wahr]" Falsch zurück?



Answers

not x in y wird als x not in y ausgewertet

Sie können genau sehen, was passiert, indem Sie den Code zerlegen. Der erste Fall funktioniert wie erwartet:

>>> x = lambda: False in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (False)
              3 LOAD_GLOBAL              0 (False)
              6 LOAD_GLOBAL              1 (True)
              9 BUILD_LIST               2
             12 COMPARE_OP               6 (in)
             15 RETURN_VALUE

Der zweite Fall ergibt True not in [False, True] , was eindeutig False :

>>> x = lambda: not(True) in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (True)
              3 LOAD_GLOBAL              1 (False)
              6 LOAD_GLOBAL              0 (True)
              9 BUILD_LIST               2
             12 COMPARE_OP               7 (not in)
             15 RETURN_VALUE        
>>> 

Was du stattdessen ausdrücken wolltest, war (not(True)) in [False, True] , was wie erwartet True , und du kannst sehen warum:

>>> x = lambda: (not(True)) in [False, True]
>>> dis.dis(x)
  1           0 LOAD_GLOBAL              0 (True)
              3 UNARY_NOT           
              4 LOAD_GLOBAL              1 (False)
              7 LOAD_GLOBAL              0 (True)
             10 BUILD_LIST               2
             13 COMPARE_OP               6 (in)
             16 RETURN_VALUE        
Question

Wenn ich das mache:

>>> False in [False, True]
True

Das gibt True . Einfach weil False in der Liste ist.

Aber wenn ich es mache:

>>> not(True) in [False, True]
False

Das gibt False . Wobei not(True) gleich False :

>>> not(True)
False

Warum?




Neben den anderen Antworten, die erwähnt haben, dass die Priorität not niedriger ist als in , entspricht Ihre Aussage tatsächlich:

not (True in [False, True])

Beachten Sie jedoch, dass Python, wenn Sie Ihre Bedingung nicht von den anderen trennen, zwei Rollen verwenden wird ( precedence oder chaining ), um das zu trennen, und in diesem Fall hat Python Vorrang. Beachten Sie außerdem, dass Sie, wenn Sie eine Bedingung trennen möchten, die gesamte Bedingung in Klammern setzen müssen, nicht nur das Objekt oder den Wert:

(not True) in [False, True]

Aber wie bereits erwähnt, gibt es eine weitere Modifikation von Python auf Operatoren, die verkettet ist :

Basierend auf Python- 3.x :

Beachten Sie, dass Vergleiche, Mitgliedschaftstests und Identitätstests alle den gleichen Vorrang haben und eine Links-nach-Rechts- Verkettung aufweisen, wie im Abschnitt "Vergleiche" beschrieben.

Zum Beispiel ist das Ergebnis der folgenden Anweisung False :

>>> True == False in [False, True]
False

Weil Python die Anweisungen wie folgt verketten wird:

(True == False) and (False in [False, True])

Was genau False and True , ist False .

Sie können davon ausgehen, dass das zentrale Objekt zwischen zwei Operationen und anderen Objekten geteilt wird (in diesem Fall False).

Beachten Sie, dass dies auch für alle Vergleiche gilt, einschließlich Mitgliedschafts- und Identitätstestoperationen, die folgenden Operanden folgen:

in, not in, is, is not, <, <=, >, >=, !=, ==

Beispiel:

>>> 1 in [1,2] == True
False

Ein anderes berühmtes Beispiel ist der Nummernbereich:

7<x<20

was gleich ist:

7<x and x<20   



Um einige der anderen Antworten zu verdeutlichen, ändert das Hinzufügen von Klammern nach einem unären Operator nicht die Priorität. not(True) bindet nicht fester an True . Es ist nur ein überflüssiger Satz Klammern um True . Es ist ungefähr dasselbe wie (True) in [True, False] . Die Klammern machen nichts. Wenn die Bindung enger sein soll, müssen Sie die Klammern um den gesamten Ausdruck legen, also sowohl den Operator als auch den Operanden, dh (not True) in [True, False] .

Um dies auf eine andere Weise zu sehen, bedenken Sie

>>> -2**2
-4

** bindet enger als - , weshalb Sie das Negativ von zwei quadrierten erhalten, nicht das Quadrat von negativen zwei (was positiv vier wäre).

Was, wenn du das Quadrat der negativen zwei haben wolltest? Natürlich würden Sie Klammern hinzufügen:

>>> (-2)**2
4

Es ist jedoch nicht vernünftig zu erwarten, dass das Folgende 4 ergibt

>>> -(2)**2
-4

weil -(2) dasselbe ist wie -2 . Die Klammern machen absolut nichts. not(True) ist genau das Gleiche.




Es geht nur um die Priorität des Operators ( in ist stärker als not ). Aber es kann leicht durch Hinzufügen von Klammern an der richtigen Stelle korrigiert werden:

(not(True)) in [False, True]  # prints true

Schreiben:

not(True) in [False, True]

ist das gleiche wie:

not((True) in [False, True])

was aussieht, wenn True in der Liste ist und gibt das "nicht" des Ergebnisses zurück.




Related