x不在y中"或"不在y中的x

120 投票
6 回答
21685 浏览
提问于 2025-04-17 09:35

在测试某个元素是否属于某个集合时,我们可以使用:

x not in y

或者可以用:

not x in y

这个表达式的具体含义会根据 xy 的不同而有所变化。比如,它可以用来检查一个字符串是否是另一个字符串的一部分,或者检查一个元素是否在列表中,或者检查一个字典中某个键是否存在。

  • 这两种写法总是等价的吗?
  • 有没有更推荐的写法?

6 个回答

11

这两种写法的意思是一样的,但pycodestyle Python 风格指南检查工具(以前叫 pep8)更喜欢使用 not in 这个操作符,具体在规则 E713中有说明:

E713: 检查成员资格时应该使用 not in

你也可以看看“Python if x is not Noneif not x is None 有什么区别?”,里面有类似的风格选择。

23

  1. 不,没有区别。

运算符 not in 的意思是和 in 正好相反。

Python 文档

  • 我觉得 not in 更受欢迎,因为它更明显,而且他们为它添加了一个特殊的情况。
  • 129

    它们总是给出相同的结果。

    实际上,not 'ham' in 'spam and eggs' 这个写法似乎是特别处理过的,它直接执行一个“不是在里面”的操作,而不是先执行“在里面”的操作再取反结果:

    >>> import dis
    
    >>> def notin():
        'ham' not in 'spam and eggs'
    >>> dis.dis(notin)
      2           0 LOAD_CONST               1 ('ham')
                  3 LOAD_CONST               2 ('spam and eggs')
                  6 COMPARE_OP               7 (not in)
                  9 POP_TOP             
                 10 LOAD_CONST               0 (None)
                 13 RETURN_VALUE    
    
    >>> def not_in():
        not 'ham' in 'spam and eggs'
    >>> dis.dis(not_in)
      2           0 LOAD_CONST               1 ('ham')
                  3 LOAD_CONST               2 ('spam and eggs')
                  6 COMPARE_OP               7 (not in)
                  9 POP_TOP             
                 10 LOAD_CONST               0 (None)
                 13 RETURN_VALUE    
    
    >>> def not__in():
        not ('ham' in 'spam and eggs')
    >>> dis.dis(not__in)
      2           0 LOAD_CONST               1 ('ham')
                  3 LOAD_CONST               2 ('spam and eggs')
                  6 COMPARE_OP               7 (not in)
                  9 POP_TOP             
                 10 LOAD_CONST               0 (None)
                 13 RETURN_VALUE        
    
    >>> def noteq():
        not 'ham' == 'spam and eggs'
    >>> dis.dis(noteq)
      2           0 LOAD_CONST               1 ('ham')
                  3 LOAD_CONST               2 ('spam and eggs')
                  6 COMPARE_OP               2 (==)
                  9 UNARY_NOT           
                 10 POP_TOP             
                 11 LOAD_CONST               0 (None)
                 14 RETURN_VALUE      
    

    我起初以为它们总是给出相同的结果,但我认为 not 本身只是一个优先级较低的逻辑取反运算符,可以像其他布尔表达式一样应用于 a in b,而 not in 是为了方便和清晰而存在的一个单独运算符。

    上面的反汇编结果让我大开眼界!看起来虽然 not 显然是一个逻辑取反运算符,但 not a in b 这个形式是特别处理过的,它实际上并没有使用一般的运算符。这使得 not a in ba not in b 字面上是完全相同的表达式,而不仅仅是结果相同的表达式。

    撰写回答