4

所以在python中,可以很容易地检查真值条件,并用括号优先考虑真条件的顺序,例如这些很容易理解:

>>> 3 > 2
True
>>> (3 > 2) is True
True

但是这些是什么意思,我无法理解它们为什么返回 False/True 的逻辑:

>>> 3 > 2 is True
False
>>> 3 > (2 is True)
True
>>> 5 < 3 is False > 2 is True
False
>>> 5 < 3 is False is True > 2 is True
False
>>> 3 < 5 is True is True > 2 is True
False
>>> 3 < 5 is True is True > 2 is True is not False is True
False
>>> 3 < 5 is True is (True > 2 is True is not False) is True
False
>>> 3 < 5 is True is (True > (2 is True) is not False) is True
False
>>> (3 < 5 is True is True) > 2 is (True is not False is True)
False

我知道这些不是pythonic条件,但我应该如何理解它们?还是从左到右吗?

或者是否is True或/和is False担任主席?

4

3 回答 3

3

您可以使用模块分析这些案例中的每一个,dis以准确了解发生了什么。例如:

In [1]: import dis
In [2]: def test():
   ...:     return 3 > 2 is True
   ...: 
In [3]: dis.dis(test)
  2           0 LOAD_CONST               1 (3)
              3 LOAD_CONST               2 (2)
              6 DUP_TOP             
              7 ROT_THREE           
              8 COMPARE_OP               4 (>)
             11 JUMP_IF_FALSE_OR_POP    21
             14 LOAD_GLOBAL              0 (True)
             17 COMPARE_OP               8 (is)
             20 RETURN_VALUE        
        >>   21 ROT_TWO             
             22 POP_TOP             
             23 RETURN_VALUE

这意味着堆栈在每一步之后看起来像这样:

 0: 3
 3: 3 2
 6: 3 2 2
 7: 2 3 2
 8: 2 True
11: 2
14: 2 True
17: False (comparison was: "2 is True")
20: (False is returned)

对我来说,老实说,它看起来像是 Python 中的一个错误。也许有一些很好的解释为什么会发生这种情况,但我会在上游报告。

只是以等效的方式重写它,代码会:

if 3 > 2:
    if 2 is True:
        return True
return False

编辑:也许它实际上有一些奇怪的意义。考虑检查链式不等式是如何工作的:

3 > 2 > 1  ==  3 > 2 and 2 > 1

如果它概括为:

x op1 y op2 z == x op1 y and y op2 z

这将解释结果。

Edit2:这实际上与文档匹配。看看链式比较:https ://docs.python.org/2/reference/expressions.html#not-in

comparison    ::=  or_expr ( comp_operator or_expr )*
comp_operator ::=  "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
                   | "is" ["not"] | ["not"] "in"

is被认为与 一样好比较>,因此应用了多重比较的标准扩展。

其他比较现在应该很清楚了。唯一需要的奇怪的新细节是:True == 1, False == 0, 所以3 > False3 > (2 is True). 大多数其他人可以用扩展来解释。例如:

5  <     3     is       False       >     2     is True  == False
(5 < 3) and (3 is False) and (False > 2) and (2 is True) == False
于 2015-11-27T00:06:04.303 回答
2

Booleanpython 中的 type 是int. 所以True实际上是 1 和False0。

Python 中的所有比较操作都具有相同的优先级(>, <, >=, <=, ==, !=, is [not], [not] in)。

比较可以任意链接,例如,x < y <= z等价于x < y and y <= z,除了 y 只计算一次(但在两种情况下,当x < y发现 z 为假时,根本不计算 z)。

形式上,如果a, b, c, ..., y,z是表达式并且op1, op2, ...,opN是比较运算符,则a op1 b op2 c ... y opN z等价于a op1 b and b op2 c and ... y opN z,除了每个表达式最多计算一次。

请参阅Python 语言参考

于 2015-11-27T00:17:20.147 回答
1

首先,您可能需要一个小备忘单来了解评估的顺序。这些运算符中的大多数都在同一个括号中,因此从左到右进行评估。有了这些知识,这些例子就可以翻译成它们的“真实”含义:

(3 < 5 is True is True) > 2 is (True is not False is True)

相当于:(实际上没有__is__and __not__,因为这些是不能重载的关键字。这是为了说明目的)

(3.__lt__(5).__is__(True).__is__(True)).__gt__(2).__is__(True.__is__(False).__not__().__is__(True))

我可能会省略此处描述的一些细节。好消息是您(希望)永远不会编写如此复杂的表达式,以至于您需要检查文档以了解它的作用。

编辑:没关系,它不适用于比较。比较是“成对地”进行比较的,就像 viraptor 的回答中描述的那样。

于 2015-11-27T00:11:48.650 回答