cs258 »

Truthiness in Python

One nice thing in Python (as in many other languages) is that any object can be interpreted as true or false. For example, if and while, test only for Truthiness, i.e. whether the object is interpreted as True. So it's a good idea to know how Truthy-ness is defined for different datatypes:

Note: The "==" operator tests just the value and the "is" operator tests whether two items refer to the same object. For example, 1==1.0, but not(1 is 1.0). Here, if x is None then we can say that x points to the same object as the None literal.

  1. None is interpreted as false.
  2. Integers/Floats: 0 and 0.0 interpreted, *everything else* is interpreted as true (including negative numbers).
  3. Strings: "" is interpreted as false, everything else as true.
  4. Sets, Tuples, Lists, Containers:

    • empty containers interpreted as false: '{}', [], (,)
    • (equivalent to the empty constructor: interpreted as false): dict(), tuple(), list(), set()
    • container with at least one item of any kind interpreted as true: {1:1}, [None], (3, 4, 5), etc
  5. Other objects decide their own truthiness with the __nonzero__() method.

    • if the class doesn't define a __nonzero__() method, then
      • if the class defines the __len__() method, then the Truthiness of the object is determined by whether the __len__() method returns a nonzero value
      • if the class doesn't define __len__(), then the object is considered true.

Basically, it breaks down to: 0, None, and empty containers are interpreted as false.

Hope this has been helpful!

(I'm going to post a short note in the answers about checking for None vs. checking for truthiness, because it was too long for to include right in this post)

Side Note: checking for None vs. checking for truthiness

often, you want to know specifically that something is None and it can be tempting to just write it like the following:

def checks_for_truth(some_value):
   if some_value:
      print "YAY!"
   else:
      print "BOO!"

The problem is that this can produce unexpected behavior if you get something that is "Falsey" but you were just looking for non-None (or for a specific set of values). Let's compare the first function with another simple one:

def checks_for_None(some_value):
   if some_value is not None:
      print "YAY!"
   else:
      print "BOO!"

So, let's take some inputs:

>>> checks_for_truth("apples"), checks_for_none("apples")
YAY!
YAY!
>>> checks_for_truth([]), checks_for_none([])
BOO!
YAY!
>>> checks_for_truth(""), checks_for_none("")
BOO!
YAY!
>>> checks_for_truth(15), checks_for_none(15)
YAY!
YAY!
>>> checks_for_truth(0), checks_for_none(0) # okay, seeing a pattern
BOO!
YAY!
>>> checks_for_truth(-10), checks_for_none(-10)
YAY!
YAY!
>>> checks_for_truth(None), checks_for_none(None)
BOO!
BOO!

Hopefully this demonstrates the point.