pythoncomparison-operators

Why does the expression 0 < 0 == 0 return False in Python? (How are chained comparisons interpreted?)


I found a strange construct in this code from the standard library Queue.py in Python 2.6:

def full(self):
    """Return True if the queue is full, False otherwise
    (not reliable!)."""
    self.mutex.acquire()
    n = 0 < self.maxsize == self._qsize()
    self.mutex.release()
    return n

Apparently, if maxsize is 0 the queue is never full. But how does this work? Why does 0 < 0 == 0 evaluate as False? No matter which operation is applied first, it seems like the result should be True, and indeed I get that result when adding parentheses:

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

See also Is "x < y < z" faster than "x < y and y < z"? for details on how the feature is implemented.


Solution

  • Python has special case handling for sequences of relational operators to make range comparisons easy to express. It's much nicer to be able to say 0 < x <= 5 than to say (0 < x) and (x <= 5).

    These are called chained comparisons.

    With the other cases you talk about, the parentheses force one relational operator to be applied before the other, and so they are no longer chained comparisons. And since True and False have values as integers you get the answers you do out of the parenthesized versions.