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 not
da solo fosse semplicemente un operatore di negazione logica a bassa precedenza, che poteva essere applicato a in b
facilmente come qualsiasi altra espressione booleana, mentre not in
era un operatore separato per comodità e chiarezza .
Lo smontaggio sopra è stato rivelatore! Sembra che mentre not
ovviamente è 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 b
letteralmente la stessa espressione di a not in b
, piuttosto che semplicemente un'espressione che restituisce lo stesso valore.
not x in xs
nei documenti.