如果循环:"x not in"与"not x in"

ava*_*riu 52 python loops if-statement

我注意到这两个都是一样的:

if x not in listif not x in list.

在某些情况下两者之间是否存在某种差异?是否有理由同时拥有这两者,或者只是因为某些人写一个或另一个更自然?

我更有可能在其他人的代码中看到哪一个?

Ale*_*lli 67

这两个表单构成相同的字节码,您可以清楚地验证:

>>> 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        
Run Code Online (Sandbox Code Playgroud)

显然他们在语义上是相同的.

作为一种风格问题,PEP 8没有提到这个问题.

就个人而言,我非常喜欢这种if x not in y形式 - 这使得它立即变得明确,这not in是一个单一的操作员,并且 "读起来​​像英语". if not x in y可能误导一些读者认为它意味着if (not x) in y,读起来有点像英语,并且绝对没有补偿优势.

  • PEP 8提到了一个类似的首选项:“使用`is not`运算符,而不是`not ... is`。虽然这两个表达式在功能上相同,但前者更易读,更可取。” (3认同)

kil*_*own 6

>>> 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  
Run Code Online (Sandbox Code Playgroud)

当你做"不是在b"时,它将需要转换为(不在)

所以,正确的方式是"不在b".