"x not in y" or "not x in 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?
19781 次浏览

在 Python 中,没有区别,也没有偏好。

  1. 不,没有区别。

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

    Python 文档

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

从句法上来说,它们是一样的。我会很快地指出,'ham' not in 'spam and eggs'传达了更清晰的意图,但我看到过代码和场景中,not 'ham' in 'spam and eggs'传达了比其他更清晰的意图。

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

事实上,not 'ham' in 'spam and eggs'似乎是特殊情况下执行一个“ not In”操作,而不是执行一个“ In”操作,然后否定结果:

>>> 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在字面上是相同的表达式,而不仅仅是一个导致相同值的表达式。

其他人已经非常清楚地表明,这两种说法在相当低的水平上是等同的。

然而,我不认为有人已经强调足够,因为这留给你的选择,你应该

选择使代码尽可能可读的表单。

而且不一定像 to anyone那样具有可读性,即使这当然是一个很好的目标。不,确保代码是尽可能可读的 敬你,因为你是谁是最有可能回到这个代码后,试图读取它。

它们在含义上是相同的,但是 Pycodestyle Python 样式指南检查器(以前称为 pep8)更喜欢 rule E713中的 not in操作符:

E713: 会员测试应为 not in

另请参阅 “ Python ABC0还是 if not x is None?”,了解非常相似的风格选择。