Truthy and Falsy Values

Concepts covered: Boolean Operators

Every Python object has a truth value. You can read it with bool(x), and and consults it, as do or and not. Among the built-in types, the false values form a short, fixed list: False, None, every numeric zero (0, 0.0, Decimal("0.00")), and every empty container ("", [], (), {}). Every other built-in value is truthy, including several a human would read as false. A class you define can set its own truth value, which the last part of this section covers.

Valuebool(value)Why
`0`Falsenumeric zero
`-1`Trueany nonzero number
`0.0`Falsenumeric zero
`float("nan")`TrueNaN is not zero
`""`Falseempty string
`" "`Truea space is a character
`"0"`Truea 1-character string
`"False"`Truea 5-character string
`None`Falsealways false
`[]`Falseempty list
`[0]`Truea list holding 1 item
from decimal import Decimal

print(bool(0), bool(0.0), bool(Decimal("0.00")), bool(None))
print(bool(""), bool(" "), bool("0"), bool("False"))
print(bool(-1), bool(float("nan")), bool([]), bool([0]))
is_active = "False"
print(bool(is_active), is_active == "True")

Output:

False False False False
False True True True
True True False True
True False

The last line is a classic ingestion bug. A CSV export or a web form delivers is_active as the text "False", and bool() reports True for any non-empty string. bool() checks emptiness and ignores meaning, so a text flag needs an explicit comparison against the spelling the source uses.

What not, and, or return

not x always returns a real bool: not "" is True and not 5 is False. and and or still return an operand, now judged by truthiness: "" or "unknown" is "unknown", 0 and 1/0 is 0 without dividing, and "eu" and 42 is 42. Because bool is a subclass of int, True + True is 2, which is why adding up comparison results counts how many were true.

What does this print?

print(bool("0"), bool(0.0), bool([0]), not None)

Falsy and missing are different facts

The retry setting in the short-circuit section already showed or treating 0 and None as the same value. What remains is choosing the right test for each field, and the field's meaning decides it. For units_sold, a store that sold 0 units reported a real number, while a store whose feed never arrived reported None. units_sold is None finds broken feeds; units_sold == 0 finds stores that opened and sold nothing. A daily report usually needs both counts, kept apart, because one is an engineering incident and the other is a sales fact. Keep truthiness for fields where every false value means the same thing. In an optional comment field, "" and None both mean nobody wrote one.

Truthiness: not units_sold
  • None: flagged
  • 0: flagged
  • 12: passes
  • Fits when every false value means nothing arrived
Identity: units_sold is None
  • None: flagged
  • 0: passes
  • 12: passes
  • Fits when 0 is a real measurement

Truth values for your own classes

An instance of a class you define is truthy by default, whatever its attributes hold. Defining __bool__ lets the class decide: Python calls it whenever the object meets bool() or not, and the same goes for and and or. The method must return a real bool; returning 1 raises TypeError: __bool__ should return bool, returned int.

class Batch:
    def __init__(self, row_count):
        self.row_count = row_count

    def __bool__(self):
        return self.row_count > 0


class Plain:
    pass


print(bool(Batch(0)), bool(Batch(250)), bool(Plain()))
print(Batch(0) or "nothing to load")

Output:

False True True
nothing to load

Batch(0) is false because its __bool__ returned False, so or passes over it and returns the fallback string. Plain() defines no __bool__ and is truthy even though it holds nothing. A loader can then treat an empty batch like any other false value, with the class itself deciding what empty means.

About this lesson

This section is part of the Python Expressions: Advanced lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.