我注意到这两者的作用相同:
if x not in list
和 if not x in list
.
在某些情况下,它们之间是否有区别? 是否有其存在的原因,还是只是因为有些人更自然地写其中一种?
在其他人的代码中,哪一种更常见?
我注意到这两者的作用相同:
if x not in list
和 if not x in list
.
在某些情况下,它们之间是否有区别? 是否有其存在的原因,还是只是因为有些人更自然地写其中一种?
在其他人的代码中,哪一种更常见?
这两种形式生成的字节码完全相同,您可以清楚地验证:
>>> 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
,读起来有点不像英语,并且没有任何补偿优势。
is not
运算符而不是not ... is
。虽然这两个表达式在功能上是相同的,但前者更易读且更受推崇。” - Walter Tross>>> 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 x in L
没有明确禁止,因为那样做是愚蠢的。x not in L
是明确允许的(尽管它编译成相同的字节码),因为它更易读。
然而,大家都使用x not in L
。
a not in b
时,它使用的是 not in
运算符,而 not a in b
使用的是 in
运算符,然后取反结果。但是 not in
运算符被定义为返回与 not a in b
相同的结果,因此它们完全相同。来自 文档:
类似地,还有运算符
in
和not in
用于测试集合成员资格。如果x
是集合s
的成员,则x in s
计算结果为真,否则为假。x not in s
返回x in s
的否定。
a is not b
与 not a is b
。dis
模块时,它显示它们都使用not in
进行比较,尽管文档中说的不是这样... - avacariu这只是个人偏好。你也可以比较if x != 3
和if not x == 3
。你展示的这两个表达式之间没有区别。
!=
调用 __ne__
,而 ==
调用 __eq__
。在特定情况下,你的示例可能会产生不同的结果。 - John La Rooy