“ x不在y”或“ x不在y”

问题:“ x不在y”或“ x不在y”

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

x not in y

或者:

not x in y

取决于x和,此表达式可能有许多可能的上下文y。例如,它可能用于子字符串检查,列表成员资格,字典键存在。

  • 两种形式总是相等的吗?
  • 有首选的语法吗?

When testing for membership, we can use:

x not in y

Or alternatively:

not x in y

There can be many possible contexts for this expression depending on x and y. It could be for a substring check, list membership, dict key existence, for example.

  • Are the two forms always equivalent?
  • Is there a preferred syntax?

回答 0

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

实际上,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 b实际上使表达式与相同a not in b,而不仅仅是产生相同值的表达式。

They always give the same result.

In fact, not 'ham' in 'spam and eggs' appears to be special cased to perform a single “not in” operation, rather than an “in” operation and then negating the result:

>>> 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      

I had thought at first that they always gave the same result, but that not on its own was simply a low precedence logical negation operator, which could be applied to a in b just as easily as any other boolean expression, whereas not in was a separate operator for convenience and clarity.

The disassembly above was revealing! It seems that while not obviously is a logical negation operator, the form not a in b is special cased so that it’s not actually using the general operator. This makes not a in b literally the same expression as a not in b, rather than merely an expression that results in the same value.


回答 1

  1. 不,没有区别。

    运算符not in被定义为具有的反真值in

    Python文档

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

  1. No, there is no difference.

    The operator not in is defined to have the inverse true value of in.

    Python documentation

  2. I would assume not in is preferred because it is more obvious and they added a special case for it.

回答 2

它们的含义相同,但是pycodestyle Python样式指南检查器(以前称为pep8)更喜欢规则E713中not in运算符:

E713:会员资格测试应为 not in

另请参见“ Python if x is not Noneif not x is None?” 选择非常相似的样式

They are identical in meaning, but the pycodestyle Python style guide checker (formerly called pep8) prefers the not in operator in rule E713:

E713: test for membership should be not in

See also “Python if x is not None or if not x is None?” for a very similar choice of style.


回答 3

其他人已经非常清楚地表明,这两个语句在相当低的水平上是等效的。

但是,我认为尚未有人对此施加过足够的压力,因为这让您自己选择,您应该

选择使代码尽可能可读的形式。

并且不一定对任何人都可读,即使这当然是一个不错的目标。不,请确保该代码对您来说尽可能易读,因为您是最有可能在稍后返回此代码并尝试阅读该代码的人。

Others have already made it very clear that the two statements are, down to a quite low level, equivalent.

However, I don’t think that anyone yet has stressed enough that since this leaves the choice up to you, you should

choose the form that makes your code as readable as possible.

And not necessarily as readable as possible to anyone, even if that’s of course a nice thing to aim for. No, make sure the code is as readable as possible to you, since you are the one who is the most likely to come back to this code later and try to read it.


回答 4

在Python中,没有区别。而且没有偏好。

In Python, there is no difference. And there is no preference.


回答 5

从句法上讲,它们是相同的陈述。我会很快指出,它'ham' not in 'spam and eggs'传达了更清晰的意图,但是我已经看到not 'ham' in 'spam and eggs'了比其他传达了更清晰含义的代码和方案。

Syntactically they’re the same statement. I would be quick to state that 'ham' not in 'spam and eggs' conveys clearer intent, but I’ve seen code and scenarios in which not 'ham' in 'spam and eggs' conveys a clearer meaning than the other.