使用"not"和"in"关键字的语法顺序

wim*_*wim 91 python syntax

在测试会员资格时,我们可以使用:

x not in y
Run Code Online (Sandbox Code Playgroud)

或者:

not y in x
Run Code Online (Sandbox Code Playgroud)

根据x和,这个表达式可能有许多可能的上下文y.例如,它可以用于子字符串检查,列表成员资格,字典密钥存在.

  • 这两种形式总是相同吗?
  • 有首选语法吗?

Ben*_*Ben 104

他们总是给出相同的结果.

实际上,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      
Run Code Online (Sandbox Code Playgroud)

我一开始认为它们总是给出相同的结果,但not它本身就是一个低优先级逻辑否定运算符,它可以a in b像任何其他布尔表达式一样容易地应用,而not in为了方便和清晰,它是一个单独的运算符.

上面的反汇编揭示了!看起来虽然not显然是一个逻辑否定运算符,但表单not a in b是特殊的,因此它实际上并没有使用泛型运算符.这not a in b与字面上的表达式相同a not in b,而不仅仅是导致相同值的表达式.

  • 你已经遇到了[CPython peephole optimization](http://hg.python.org/cpython/file/ed8b0ee1c531/Python/peephole.c#l405); 编译时优化,其他Python实现,如Jython和IronPython可以自由忽略或复制(它不是语言规范的一部分). (9认同)
  • 请记住,这只是一个实现细节.我甚至在文档中都没有提到"不是xs中的x". (2认同)

ick*_*fay 13

  1. 不,没有区别.

    运算符not in被定义为具有倒数真值in.

    - Python文档

  2. 我认为这not in是首选,因为它更明显,他们为它添加了一个特殊情况.


tri*_*cot 5

它们的含义相同,但pep8 Python样式指南检查器更喜欢规则E713中not in操作符:

E713:会员资格测试应该是 not in

另见"Python if x is not Noneif not x is None?" 对于非常相似的风格选择.