True/False value testing

Chris Angelico rosuav at gmail.com
Thu Jan 7 06:50:28 EST 2016


On Thu, Jan 7, 2016 at 10:19 PM, Marko Rauhamaa <marko at pacujo.net> wrote:
> Chris Angelico <rosuav at gmail.com>:
>
>> However, none of these will compare *equal* to the Boolean values True
>> and False, save for the integers 1 and 0. In fact, True is a special
>> form of the integer 1, and False is a special form of the integer 0;
>
> Stirring the pot:
>
>    >>> (2 < 3) is True
>    True
>
> but is that guaranteed?

Yes. When you do comparisons involving integers, the result is an
actual boolean value - not just a truthy value, but the exact value
True or False. Those values, being singletons (or a doubleton, or
whatever you want to call it), will always be the same objects, ergo
the "is True" part must always pass.

However, if arbitrary objects are thrown into the mix, the guarantee
doesn't hold. Here's one way of implementing a "sticky NaN" that
infects all operations:

class NaN:
    def __lt__(self, other): return self
    __gt__ = __ge__ = __le__ = __lt__
    def __eq__(self, other): return False
    def __ne__(self, other): return True
    def __new__(cls):
        if not hasattr(cls, "_inst"):
            cls._inst = super().__new__(cls)
        return cls._inst
    def __repr__(self): return "NaN"

NaN = NaN()


And it looks something like this:

>>> NaN < 1
NaN
>>> 1 < NaN
NaN
>>> NaN > 1
NaN
>>> 1 > NaN
NaN
>>> NaN == NaN
False

Similarly, numpy arrays overload operators to perform elementwise comparisons:

>>> import numpy
>>> numpy.array(range(10))
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> _ < 5
array([ True,  True,  True,  True,  True, False, False, False, False,
False], dtype=bool)

But with integers, and with most other built-in types, the comparison
operators are indeed guaranteed to return either True or False.

ChrisA



More information about the Python-list mailing list