Why does the expression 0 < 0 == 0 return False in Python?

前端 未结 9 1505
误落风尘
误落风尘 2020-11-22 01:48

Looking into Queue.py in Python 2.6, I found this construct that I found a bit strange:

def full(self):
    \"\"\"Return True if the queue is full, False oth         


        
相关标签:
9条回答
  • 2020-11-22 02:21

    Looking at the disassembly (the bytes codes) it is obvious why 0 < 0 == 0 is False.

    Here is an analysis of this expression:

    >>>import dis
    
    >>>def f():
    ...    0 < 0 == 0
    
    >>>dis.dis(f)
      2      0 LOAD_CONST               1 (0)
             3 LOAD_CONST               1 (0)
             6 DUP_TOP
             7 ROT_THREE
             8 COMPARE_OP               0 (<)
            11 JUMP_IF_FALSE_OR_POP    23
            14 LOAD_CONST               1 (0)
            17 COMPARE_OP               2 (==)
            20 JUMP_FORWARD             2 (to 25)
       >>   23 ROT_TWO
            24 POP_TOP
       >>   25 POP_TOP
            26 LOAD_CONST               0 (None)
            29 RETURN_VALUE
    

    Notice lines 0-8: These lines check if 0 < 0 which obviously returns False onto the python stack.

    Now notice line 11: JUMP_IF_FALSE_OR_POP 23 This means that if 0 < 0 returns False perform a jump to line 23.

    Now, 0 < 0 is False, so the jump is taken, which leaves the stack with a False which is the return value for the whole expression 0 < 0 == 0, even though the == 0 part isn't even checked.

    So, to conclude, the answer is like said in other answers to this question. 0 < 0 == 0 has a special meaning. The compiler evaluates this to two terms: 0 < 0 and 0 == 0. As with any complex boolean expressions with and between them, if the first fails then the second one isn't even checked.

    Hopes this enlightens things up a bit, and I really hope that the method I used to analyse this unexpected behavior will encourage others to try the same in the future.

    0 讨论(0)
  • 2020-11-22 02:22

    I'm thinking Python is doing it's weird between magic. Same as 1 < 2 < 3 means 2 is between 1 and 3.

    In this case, I think it's doing [middle 0] is greater than [left 0] and equal to [right 0]. Middle 0 is not greater than left 0, so it evaluates to false.

    0 讨论(0)
  • 2020-11-22 02:26
    >>> 0 < 0 == 0
    False
    

    This is a chained comparison. It returns true if each pairwise comparison in turn is true. It is the equivalent to (0 < 0) and (0 == 0)

    >>> (0) < (0 == 0)
    True
    

    This is equivalent to 0 < True which evaluates to True.

    >>> (0 < 0) == 0
    True
    

    This is equivalent to False == 0 which evaluates to True.

    >>> 0 < (0 == 0)
    True
    

    Equivalent to 0 < True which, as above, evaluates to True.

    0 讨论(0)
提交回复
热议问题