“不在”和“不是”两个运营商?如果是这样,它们是否与“not x in ...”和“not x is ..”不同?

时间:2010-02-06 02:07:24

标签: python

我一直喜欢这些:

not 'x' in 'abc'
not 'x' is 'a'

(假设,当然每个人都知道inis超出优先级not - 我可能应该使用括号)而不是更多(英语)语法:

'x' not in 'abc'
'x' is not 'a'

但是没想到为什么直到我意识到他们没有语法意义

'x' == not 'a'
'x' not == 'a'

当然都会抛出语法错误。

所以我认为他们都是双字运营商。但是,documentation仅引用is not,并未提及not in作为运算符。我是否可能误解了语法?

如果他们都是运营商,那么他们与非语法对手有什么不同(甚至是微妙的)?

如果它们是相同的,那么为什么它们存在? Zen of Python(......“一个 - 最好只有一个 - 显而易见的方式”......似乎是不感兴趣的。)

我很抱歉,如果已经讨论过已经死亡,我只是很难找到像“不是”这样的搜索字词。

5 个答案:

答案 0 :(得分:7)

使用dis模块检查是否有任何差异很容易:

>>> dis.dis(compile('not a in b','','exec'))
  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        
>>> dis.dis(compile('a not in b','','exec'))
  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

请参阅?尴尬的第一种形式(经常混淆那些不能立即告诉notin运算符的相对优先级的人)被编译成完全相同的字节码,而不是混淆任何第二种形式,使用单个not in运算符。类似地:

>>> dis.dis(compile('not a is b','','exec'))
  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 COMPARE_OP               9 (is not)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        
>>> dis.dis(compile('a is not b','','exec'))
  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 COMPARE_OP               9 (is not)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

这两种形式 - 愚蠢,令人困惑的第一种形式和优雅的第二种形式 - 与完全相同的代码进行比较,并且都使用is not运算符。

当然没有充分的理由使用可能会使读者感到困惑的表单(除非你喜欢为读取代码的人设置陷阱! - ),但是在执行语义和速度方面没有任何区别。

答案 1 :(得分:4)

来自python 2.6.4 docs:http://docs.python.org/reference/expressions.html >

  

未定义的操作员被定义为具有   in的反向真值。

     

运营商是否正在测试   对象标识:如果和,则x为y   只有当x和y是同一个对象时。 X   不是y产生相反的事实   值。

例如:“x not in y”与“not x in y”完全相同,“x is not y”与“not x is y”相同。

“x not == y”不解析,但“x!= y”确实如此,所以那里也有等价......

HTH。

答案 2 :(得分:2)

上面已经回答了你的问题的其余部分,但我将解决最后一个问题:Python的禅位。

“应该只有一种方法可以做到这一点”并不意味着在数学意义上。如果是,则没有!=运算符,因为这只是==的反转。同样,没有andor ---毕竟,你可以只使用一个nand命令。 “单向”口头禅是有限的:应该只有一种高级方式。当然,这种高级方式可以被分解 - 你可以编写自己的math.tan,而你永远不需要使用urllib --- socket总是在那里。但正如urllib.open是原始socket操作的更高级别封装一样,not innotin的更高级别封装。你可能会说,这有点平庸。但您使用x != y代替not (x == y)

答案 3 :(得分:2)

您的文档参考与语法无关。 Try thisis notnot in都是双字运算符。

答案 4 :(得分:0)

x in a测试元素x是否在a中(在这种情况下可能是列表或字符串或某些字符串),如果是,则返回True

x not in a类似,但如果x位于。

,则返回False

另一方面,x is not a类似于x != anot x is a

就像你说的那样,x ==不是5会给你一个错误的排序