x不在" 与 "不在x中

80 投票
5 回答
41093 浏览
提问于 2025-04-16 02:46

我注意到这两种写法效果是一样的:

if x not in listif not x in list

这两种写法在某些情况下有什么区别吗?为什么会有这两种写法,难道只是因为有些人觉得其中一种写起来更顺手吗?

我在别人写的代码中更可能看到哪一种呢?

5 个回答

4

not x in L 这个写法并没有被明确禁止,因为这样做没什么意义。x not in L 这个写法是被允许的(虽然它们编译成的字节码是一样的),因为这样看起来更容易理解。

不过,大家通常都是用 x not in L 这个写法。

9
>>> 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)”的形式。

所以,正确的写法是“a not in b”。

104

这两种写法生成的字节码是完全一样的,你可以很清楚地验证这一点:

>>> 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(也就是把“x”的值反转),读起来不太像英语,而且没有任何好处。

使用 if x not in y 这种写法在有多个条件时,代码的可读性也会更好。例如,考虑这个语句 if not x in y and x in m。随便看一下的人可能会以为它的意思是 if not (x in y and x in m),但实际上代码是 if (not x in y) and (x in m),这会让人感到意外。因此,把 not 放在它所属的 in 操作符旁边,可以清楚地表明 not in 只适用于那个特定的条件,而不是所有条件。

因此,if x not in y and x in m 在可读性上有很多好处,不管编程经验如何,理解起来都更简单。此外,not in 是“not in”字节码操作符的官方名称(在上面的反汇编中可以看到),这进一步确认了 not in 是 Python 推荐的写法。

我们再考虑一个类似的语句。就是 is not 条件。如果你试图写 if not x is True,就会很明显地看到这种写法有多么奇怪和反向。它们在逻辑上都没有意义,但在 is not 的例子中就显得特别明显。

总之,if X is not Yif X not in Y 是编写这类 Python 语句的推荐方式。

撰写回答