"X non in y" o "non x in y"


97

Durante il test per l'iscrizione, possiamo utilizzare:

x not in y

Oppure in alternativa:

not x in y

Ci possono essere molti possibili contesti per questa espressione a seconda di xe y. Potrebbe essere per un controllo della sottostringa, l'appartenenza a una lista, l'esistenza di una chiave di comando, per esempio.

  • Le due forme sono sempre equivalenti?
  • Esiste una sintassi preferita?

Risposte:


112

Danno sempre lo stesso risultato.

In effetti, not 'ham' in 'spam and eggs'sembra essere un caso speciale per eseguire una singola operazione "non in", piuttosto che un'operazione "in" e quindi negare il risultato:

>>> 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      

All'inizio avevo pensato che fornissero sempre lo stesso risultato, ma che notda solo fosse semplicemente un operatore di negazione logica a bassa precedenza, che poteva essere applicato a in bfacilmente come qualsiasi altra espressione booleana, mentre not inera un operatore separato per comodità e chiarezza .

Lo smontaggio sopra è stato rivelatore! Sembra che mentre notovviamente è un operatore di negazione logica, il modulo not a in bè un caso speciale in modo che non utilizzi effettivamente l'operatore generale. Questo rende not a in bletteralmente la stessa espressione di a not in b, piuttosto che semplicemente un'espressione che restituisce lo stesso valore.


4
Tieni presente che questo è solo un dettaglio di implementazione. Non riesco nemmeno a trovare una menzione not x in xsnei documenti.
phant0m

1
@ phant0m Assolutamente; il modo in cui dovresti pensare not x in xsè not (x in xs). Ma il fatto che sia implementato analizzandolo esattamente nello stesso bytecode x not in xsmostra molto chiaramente che devono essere sempre identici, al contrario di cose come not x == yvs x != yche dovrebbero dare lo stesso risultato, ma non devono (a seconda delle implementazioni di __eq__e __ne__coinvolti).
Ben

11
Hai riscontrato un'ottimizzazione dello spioncino CPython ; un'ottimizzazione in fase di compilazione che altre implementazioni Python come Jython e IronPython sono libere di ignorare o copiare (non fa parte delle specifiche del linguaggio).
Martijn Pieters

15

  1. No, non c'è differenza.

    L'operatore not inè definito per avere il valore vero inverso di in.

    - Documentazione Python

  2. Presumo not insia preferito perché è più ovvio e hanno aggiunto un caso speciale per questo.



3

Altri hanno già chiarito che le due affermazioni sono, fino a un livello piuttosto basso, equivalenti.

Tuttavia, non penso che qualcuno abbia ancora sottolineato abbastanza che, poiché questo lascia a te la scelta, dovresti

scegli il modulo che rende il tuo codice il più leggibile possibile.

E non necessariamente il più leggibile possibile da chiunque , anche se ovviamente è una cosa carina a cui mirare. No, assicurarsi che il codice è più leggibili possibile a te , visto che sei quello che è il più probabilità di tornare a questo codice più tardi e cercare di leggerlo.


Se lavori in un team numeroso o su un codice che probabilmente rimarrà intatto per un po ', potrebbe essere più probabile che qualcun altro debba mantenerlo.
Tommy Herbert


1

Sintatticamente sono la stessa dichiarazione. Vorrei rapidamente affermare che 'ham' not in 'spam and eggs'trasmette un intento più chiaro, ma ho visto codice e scenari in cui not 'ham' in 'spam and eggs'trasmette un significato più chiaro dell'altro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.