关于python:如果循环:“x not in”与“not x in”

If loop: “x not in” vs. “not x in”

本问题已经有最佳答案,请猛点这里访问。

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

if x not in listif not x in list

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> 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立即明确not in是单个运算符,并且"读起来像英语"。 if not x in y可能误导一些读者认为它意味着if (not x) in y,读起来有点像英语,并且绝对没有补偿优势。


1
2
3
4
5
6
7
8
9
10
11
>>> 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

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

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


not x in L未被明确禁止,因为那将是愚蠢的。显式允许x not in L(尽管它编译为相同的字节码),因为它更具可读性。

x not in L是每个人都使用的。


当您编写a not in b时,它使用not in运算符,而not a in b使用in运算符,然后否定结果。但是not in运算符被定义为返回与not a in b相同的值,因此它们完全相同。从文档:

The operators in and not in test for collection membership. x in s evaluates to true if x is a member of the collection s, and false otherwise. x not in s returns the negation of x in s.

类似地,a is not bnot a is b

添加了额外的语法,因为它使人们更容易自然地阅读它。


这只是个人喜好。您还可以比较if x != 3if not x == 3。您展示的两个表达式之间没有区别。