2015-11-26 71 views
4

因此,在python中,可以很容易地检查真值条件,并且在括号中可以优先考虑真实条件的顺序。这很容易理解:Python中的不等式和括号

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

但什么是这些平均,我无法把握的,为什么他们返回False /真逻辑:

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

我知道这些都不是Python的条件,但是我应该怎么理解他们?它是从左到右吗?

还是is True或/和is False需要主持?

回答

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 

可以解释的结果。

编辑2:这实际上匹配文档。看一看链比较: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 == 1False == 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 
+0

只是想知道,'JUMP_IF_FALSE_OR_POP'操作应该表示什么? –

+0

字面意思是什么名称:)如果堆栈顶部是假的,它会跳转。如果没有,它会弹出该值。 – viraptor

+0

对不起,我应该更具体一些:“JUMP”是什么意思? –

1

首先,你propably需要一点点的小抄知道order of evaluation。大多数这些操作符位于同一个括号内,因此从左到右进行评估。有了这些知识,这些例子可以翻译它们的“真实”的意思是:

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

相当于:(其实有没有__is____not__,因为这些都是不能超载的关键字。这是用于说明目的)

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

我可能逃得掉一些细节描述here。好处是你(希望)不会写出如此复杂的表达式,你需要检查文档以了解它的功能。

编辑:没关系,它不会以这种方式与比较工作。比较结果被比较为“一起成对”,就像viraptor的回答中所描述的一样。

+1

这实际上是不正确的。看看我的回应。仅使用比较的表达式会被专门处理。你引用的页面是“(除了比较,包括测试,它们从左到右全部具有相同的优先级和链 - 请参见比较部分和指数,从右到左分组)”。另外“不是”是字节码中的一个操作符(不管你写'不是1是2'还是'1不是2')。 – viraptor

+0

我知道这些不准确之处,但我认为我可以让他们滑倒插图。这是文档中整个部分的一个原因。 – Felk

+1

我的意思是'(3 <5是True)'不等于'3 .__ lt __(5).__是__(True)'。它是'(3 .__ lt __(5))和(5 .__ is __(True))'。 – viraptor

2

Boolean在python中键入的类型是int的子类型。所以True实际上是1和False为0

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

比较可以被任意链的,例如,x < y <= z相当于x < y and y <= z,不同之处在于计算y只有一次(但在这两种情况下Z不是在所有时x < y被发现是假的评价)。

在形式上,如果abc,...,yz是表达式和​​op1op2,...,opN是比较操作符,然后a op1 b op2 c ... y opN z相当于a op1 b and b op2 c and ... y opN z,除了每个表达在评价最多一次。

请参阅Python language reference

+0

但是只有'1'和'True'之间的值才能检查出对吗?所以'真是1'和'1是真'是假的。和“True == 1”和“1 == True”为真。 – alvas

+0

是的,'True','1'和'1.0'都是不同类型的对象,但具有相同的值。因此,对象身份运算符“是”将总是说它们是不同的。其他比较运算符将始终比较它们的值。 – user2683246