Они всегда дают один и тот же результат.
Фактически, not 'ham' in 'spam and eggs'
представляется специальным случаем для выполнения одной операции «не в», а не операции «в», а затем отрицания результата:
>>> 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
Сначала я думал, что они всегда дают один и тот же результат, но само по себе not
является просто оператором логического отрицания с низким приоритетом, который можно применять к a in b
так же легко, как и любое другое логическое выражение, тогда как not in
был отдельным оператором для удобства и ясности.
Разборка выше показала себя! Кажется, что, хотя not
, очевидно, является логическим оператором отрицания, форма not a in b
имеет специальный регистр, так что в действительности она не использует общий оператор. Это делает not a in b
буквально тем же выражением, что и a not in b
, а не просто выражением, результатом которого является то же значение.