"X nicht in y" oder "nicht x in y"

96

Beim Testen der Mitgliedschaft können wir Folgendes verwenden:

x not in y

Oder alternativ:

not x in y

Abhängig von xund kann es für diesen Ausdruck viele mögliche Kontexte geben y. Dies kann zum Beispiel für eine Teilzeichenfolgenprüfung, eine Listenmitgliedschaft oder eine Diktierschlüsselexistenz sein.

  • Sind die beiden Formen immer gleich?
  • Gibt es eine bevorzugte Syntax?
wim
quelle

Antworten:

112

Sie geben immer das gleiche Ergebnis.

Tatsächlich not 'ham' in 'spam and eggs'scheint es sich um ein spezielles Gehäuse zu handeln, das eine einzelne "Nicht-In" -Operation anstelle einer "In" -Operation ausführt und dann das Ergebnis negiert:

>>> import dis

>>> def notin():
    'ham' not in 'spam and eggs'
>>> dis.dis(notin)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE    

>>> def not_in():
    not 'ham' in 'spam and eggs'
>>> dis.dis(not_in)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE    

>>> def not__in():
    not ('ham' in 'spam and eggs')
>>> dis.dis(not__in)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

>>> def noteq():
    not 'ham' == 'spam and eggs'
>>> dis.dis(noteq)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT           
             10 POP_TOP             
             11 LOAD_CONST               0 (None)
             14 RETURN_VALUE      

Ich hatte zuerst gedacht, dass sie immer das gleiche Ergebnis liefern, aber dass dies notfür sich genommen einfach ein logischer Negationsoperator mit niedriger Priorität ist, der a in bgenauso einfach angewendet werden kann wie jeder andere boolesche Ausdruck, während er der not inEinfachheit und Klarheit halber ein separater Operator ist .

Die Demontage oben war aufschlussreich! Es scheint, dass notdas Formular offensichtlich ein logischer Negationsoperator ist, das Formular not a in bjedoch in einem speziellen Gehäuse angeordnet ist, sodass es nicht den allgemeinen Operator verwendet. Dies macht not a in bbuchstäblich den gleichen Ausdruck wie a not in bund nicht nur einen Ausdruck, der zum gleichen Wert führt.

Ben
quelle
4
Beachten Sie, dass dies nur ein Implementierungsdetail ist. Ich kann nicht einmal eine Erwähnung not x in xsin den Dokumenten finden.
Phant0m
1
@ phant0m Absolut; Die Art, wie du denken sollst, not x in xsist not (x in xs). Die Tatsache, dass es implementiert wird, indem es in genau denselben Bytecode analysiert wird, x not in xszeigt sehr deutlich, dass sie immer identisch sein müssen, im Gegensatz zu Dingen wie not x == yvs, x != ydie das gleiche Ergebnis liefern sollten , aber nicht müssen (abhängig von den Implementierungen von __eq__und __ne__beteiligt).
Ben
11
Sie sind auf eine CPython-Gucklochoptimierung gestoßen . Eine Optimierung zur Kompilierungszeit, die andere Python-Implementierungen wie Jython und IronPython ignorieren oder kopieren können (sie ist nicht Teil der Sprachspezifikation).
Martijn Pieters
15

  1. Nein, es gibt keinen Unterschied.

    Der Operator not inhat den umgekehrten wahren Wert von in.

    - Python-Dokumentation

  2. Ich würde annehmen, dass not ines bevorzugt wird, weil es offensichtlicher ist und sie einen Sonderfall dafür hinzugefügt haben.

icktoofay
quelle
3

Andere haben bereits sehr deutlich gemacht, dass die beiden Aussagen bis auf ein recht niedriges Niveau gleichwertig sind.

Ich glaube jedoch nicht, dass jemand bisher genug betont hat, dass Sie dies tun sollten, da dies die Wahl Ihnen überlässt

Wählen Sie das Formular, das Ihren Code so lesbar wie möglich macht.

Und nicht unbedingt für jeden so lesbar wie möglich , auch wenn das natürlich eine schöne Sache ist. Nein, stellen Sie sicher , der Code ist so lesbar wie möglich zu Ihnen , da Sie derjenige sind, der am wahrscheinlichsten zu diesem Code kommen später wieder und versucht , es zu lesen.

Tomas Aschan
quelle
Wenn Sie in einem großen Team oder an Code arbeiten, der wahrscheinlich für eine Weile unberührt bleibt, ist es möglicherweise wahrscheinlicher, dass jemand anderes ihn warten muss.
Tommy Herbert
2

In Python gibt es keinen Unterschied. Und es gibt keine Präferenz.

Ignacio Vazquez-Abrams
quelle
1

Syntaktisch sind sie die gleiche Aussage. Ich würde schnell sagen, dass dies eine 'ham' not in 'spam and eggs'klarere Absicht vermittelt, aber ich habe Code und Szenarien gesehen, in denen not 'ham' in 'spam and eggs'eine klarere Bedeutung als in der anderen vermittelt wird.

Makoto
quelle