Comparisons and sorting of a numeric class....

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Jan 7 18:46:03 EST 2015


Marko Rauhamaa wrote:

> Steven D'Aprano <steve at pearwood.info>:
> 
>> int 0 is a falsey object
>> NoneType None is a falsey object
>> str 'hello' is a truthy object
>> float 23.0 is a truthy object
> 
> I prefer the Scheme way:
> 
>    #f is a falsey object
> 
>    everything else is a truthy object


The Scheme way has no underlying model of what truthiness represents, just
an arbitrary choice to make a single value have one truthiness, and
everything else the other. It's just as meaningless and just as arbitrary
as the opposite would be:

    #t is True
    everything else is falsey


In both cases, you have the vast infinity of values apart from #f (or #t, as
the case may be) which are indistinguishable from each other under the
operation of "use in a boolean context". In other words, apart from #f or
#t, bool(x) maps everything to a single value. That makes it useless for
anything except distinguishing #f (or #t) from "everything else".

(I'm mixing scheme and python here, but I trust my meaning is clear.)

Given x of some type other than the Boolean type, bool(x) always gives the
same result. Since all non-Booleans are indistinguishable under that
operation, it is pointless to apply that operation to them.

I'd rather the Pascal way:

    #t is True
    #f is False
    everything else is an error


That at least gives you the benefits (if any) of strongly-typed bools.

Python has a (mostly) consistent model for truthiness: truthy values
represent "something", falsey values represent "nothing" or emptiness:

Falsey values:
  None
  Numeric zeroes: 0, 0.0, 0j, Decimal(0), Fraction(0)
  Empty strings '', u''
  Empty containers [], (), {}, set(), frozenset()

Truthy values:
  Numeric non-zeroes
  Non-empty strings
  Non-empty containers
  Any other arbitrary object


The model isn't quite perfect (I don't believe any model using truthiness
can be) but the number of gotchas in the built-ins and standard library are
very small. I can only think of two:

- datetime.time(0) is falsey. Why midnight should be falsey is an 
  accident of implementation: datetime.time objects inherit from 
  int, and midnight happens to be represented by zero seconds.

- Empty iterators are truthy. Since in general you can't tell in 
  advance whether an iterator will be empty or not until you try 
  it, this makes sense.




-- 
Steven




More information about the Python-list mailing list