Which Values Are Considered Falsy in Python?

In Python, the following objects are considered falsy (i.e. objects that evaluate to False in a boolean context):

  1. None and False;
  2. Zero of any numeric type;
  3. Empty sequences and collections;
  4. __bool__() method that returns False or __len__() method that returns 0.

None and False

The built-in constants, None and False, both evaluate to false in a boolean context. False is boolean false, obviously. For None, when you explicitly cast it to boolean for example, it's evaluated to False:

print(bool(None)) # False

Similarly, when you use None in a boolean context, it's evaluated to False:

if None:
    # do something

# equivalent to
if bool(None):
    # do something

Zero of Any Numeric Type

All zeros of numeric types (signed or unsigned) are evaluated to False when cast to boolean. For example:

print(bool(0)) # False
print(bool(-0)) # False
print(bool(+0)) # False

print(bool(0.0)) # False
print(bool(-0.0)) # False
print(bool(+0.0)) # False

print(bool(0j)) # False
print(bool(-0j)) # False
print(bool(+0j)) # False
print(bool(0b0)) # False
print(bool(0B0)) # False

print(bool(0o0)) # False
print(bool(0O0)) # False

print(bool(0x0)) # False
print(bool(0X0)) # False
from decimal import Decimal
from fractions import Fraction

print(bool(Decimal(0))) # False
print(bool(Fraction(0, 1))) # False

Similarly, when you use numeric zeroes in a boolean context, it's evaluated to False:

if 0:
    # do something

# equivalent to
if bool(0):
    # do something

However, zeroes of any other type (including string '0') are evaluated to True (and not False):

print(bool('0')) # True
print(bool('0.0')) # True
print(bool('0j')) # True
# ...

Empty Sequences and Collections

Empty sequences and collections (such as '', (), [], {}, etc.) are evaluated to False when cast to boolean. For example:

# empty str
print(bool('')) # False

# empty bytes
print(bool(b'')) # False
# empty tuple
print(bool(())) # False

# empty list
print(bool([])) # False

# empty dict
print(bool({})) # False
# empty set
print(bool(set())) # False

# empty range
print(bool(range(0))) # False

# empty bytearray
print(bool(bytearray(b''))) # False

# empty memoryview
print(bool(memoryview(b''))) # False

Similarly, when you use empty sequences or collections in a boolean context, they're evaluated to False:

if '':
    # do something

# equivalent to
if bool(''):
    # do something

Class With Custom __bool__() or __len__() Methods

A Python object is considered True unless its class has a:

  1. __bool__() method that returns False, or;
  2. __len__() method that returns 0.

For example, the following class implements a __bool__() method that returns False only if the "items" instance variable is empty:

class Cart:
    def __init__(self):
        self.items = []

    def __bool__(self):
        return len(self.items) > 0

    def add_item(self, name):
        self.items.append(name)

cart = Cart()
print(bool(cart)) # False

cart.add_item('apple')
cart.add_item('orange')

print(bool(cart)) # True

When you use this object in a boolean context, it will be evaluated to a boolean value based on the return value of the __bool__() method:

if cart:
    # do something

# equivalent to
if bool(cart):
    # do something

Consider another example where the class implements a __len__() method that returns False only if the "items" instance variable has length 0:

class Cart:
    def __init__(self):
        self.items = []

    def __len__(self):
        return len(self.items)

    def add_item(self, name):
        self.items.append(name)

cart = Cart()
print(bool(cart)) # False

cart.add_item('apple')
cart.add_item('orange')

print(bool(cart)) # True

When you use this object in a boolean context, it will be evaluated to a boolean value based on the return value of the __len__() method:

if cart:
    # do something

# equivalent to
if bool(cart):
    # do something

If both, __bool__() and __len__(), are defined in a class, then result of __bool__() takes precedence in a boolean context:

class Foo:
    # ...

    def __len__(self):
        return False

    def __bool__(self):
        return True

    # ...

foo = Foo()
print(bool(foo)) # True

This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.