This question already has an answer here:
I've noticed that both of these work the same:
if x not in list
and if not x in list
.
Is there some sort of difference between the two in certain cases? Is there a reason for having both, or is it just because it's more natural for some people to write one or the other?
Which one am I more likely to see in other people's code?
Две формы образуют идентичный байт-код, как вы можете четко убедиться:
>>> import dis
>>> dis.dis(compile('if x not in d: pass', '', 'exec'))
1 0 LOAD_NAME 0 (x)
3 LOAD_NAME 1 (d)
6 COMPARE_OP 7 (not in)
9 JUMP_IF_FALSE 4 (to 16)
12 POP_TOP
13 JUMP_FORWARD 1 (to 17)
>> 16 POP_TOP
>> 17 LOAD_CONST 0 (None)
20 RETURN_VALUE
>>> dis.dis(compile('if not x in d: pass', '', 'exec'))
1 0 LOAD_NAME 0 (x)
3 LOAD_NAME 1 (d)
6 COMPARE_OP 7 (not in)
9 JUMP_IF_FALSE 4 (to 16)
12 POP_TOP
13 JUMP_FORWARD 1 (to 17)
>> 16 POP_TOP
>> 17 LOAD_CONST 0 (None)
20 RETURN_VALUE
, поэтому очевидно, что они семантически идентичны.
Как правило, PEP 8 не упоминает об этой проблеме.
Лично я сильно предпочитаю форму if x not in y
- это сразу дает понять, что not in
является единственным оператором, и » читается как английский ". if not x in y
может ввести некоторых читателей в заблуждение, думая, что это означает if (not x) in y
, читается немного меньше, чем английский, и не имеет абсолютно никаких компенсирующих преимуществ.
>>> dis.dis(lambda: a not in b)
1 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (b)
6 COMPARE_OP 7 (not in)
9 RETURN_VALUE
>>> dis.dis(lambda: not a in b)
1 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (b)
6 COMPARE_OP 7 (not in)
9 RETURN_VALUE
когда вы делаете «not a in b», его нужно будет преобразовать в (not in)
, поэтому , правильный путь - это «а не в б».
not x in L
явно не запрещено, потому что это было бы глупо. x не в L
явно разрешен (хотя компилируется в тот же байткод), потому что он более читабелен.
x not in L
- это то, что все используют, однако.
Когда вы пишете a not in b
, используется оператор not in
, тогда как not a in b
использует оператор в операторе
, а затем отменяет результат. Но оператор not in
определен так, чтобы возвращать то же самое, что и not a in b
, поэтому они делают то же самое. Из документации :
Операторы
в
ине в
проверяют членство в коллекции.x в s
оценивается как истина, еслиx
является членом коллекцииs
, и ложью в противном случае.x not in s
возвращает отрицаниеx в s
.
Точно так же есть a is not b
по сравнению с not a is b
.
Дополнительный синтаксис был добавлен, потому что он упрощает его естественное чтение для человека.
Это просто личное предпочтение. Вы также можете сравнить if x != 3
и if not x == 3
. Нет никакой разницы между двумя выражениями, которые вы показали.