If loop: “x not in” vs. “not x in” [duplicate]

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?

52
задан Peter Mortensen 15 December 2017 в 09:47
поделиться

5 ответов

Две формы образуют идентичный байт-код, как вы можете четко убедиться:

>>> 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 , читается немного меньше, чем английский, и не имеет абсолютно никаких компенсирующих преимуществ.

67
ответ дан 7 November 2019 в 09:28
поделиться
>>> 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)

, поэтому , правильный путь - это «а не в б».

6
ответ дан 7 November 2019 в 09:28
поделиться

not x in L явно не запрещено, потому что это было бы глупо. x не в L явно разрешен (хотя компилируется в тот же байткод), потому что он более читабелен.

x not in L - это то, что все используют, однако.

3
ответ дан 7 November 2019 в 09:28
поделиться

Когда вы пишете 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 .

Дополнительный синтаксис был добавлен, потому что он упрощает его естественное чтение для человека.

3
ответ дан 7 November 2019 в 09:28
поделиться

Это просто личное предпочтение. Вы также можете сравнить if x != 3 и if not x == 3. Нет никакой разницы между двумя выражениями, которые вы показали.

0
ответ дан 7 November 2019 в 09:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: