Python Truthy & Falsy
Beginner Control Flow

Python Truthy and Falsy Values

1Python Truthy & Falsy: overview

Every Python value can be used as a condition: a short list of values (zero, empty text, empty collections, None and False) counts as False, and everything else counts as True.

GoalBy the end you can list the falsy values, check any value with bool(), write short conditions like if items:, pick defaults with or, and avoid the traps of 0 and the text "False".

Before this lesson: Python Data Types, Python if, elif and else

2Python Truthy & Falsy: diagram

How Python judges a value in an ifHow Python judges a value in an ifvaluewhat it iscounts asFalse, Nonethe "nothing" valuesFalse0, 0.0zeroFalse""empty textFalse[] () {} set()empty collectionsFalse7, -3, 0.1any other numberTrue"hi", " ", "False"any non-empty textTrue[0], [""], [[]]non-empty collectionsTruePython only asks: is there anything here? bool(value) gives the answer.
Anything that means "nothing" or "empty" is falsy, and anything that holds something is truthy. Notice that a non-empty collection is truthy even when the items inside it are falsy.

3Python Truthy & Falsy: explained step by step

When you write if something:, Python doesn't insist that something is literally True or False. It takes whatever value you give it and asks one question: does this value count as true? Every value can answer that question, so every value can be used as a condition.

The falsy values

Only a short list of values count as falsy (they act like False in a condition):

  • False and None
  • zero in any number type: 0 and 0.0
  • empty text: ""
  • empty collections: [], (), {} and set()

Everything else is truthy. The idea behind the list is "is there anything here?" Zero, nothing and empty containers hold nothing, so they count as false. Any other value holds something, so it counts as true.

Looking inside with bool()

The built-in bool() converts any value to True or False using exactly the rule that if uses, which makes it the quickest way to check a value you're unsure about.

Python
print("0      ->", bool(0))
print("0.0    ->", bool(0.0))
print('""     ->', bool(""))
print("[]     ->", bool([]))
print("()     ->", bool(()))
print("{}     ->", bool({}))
print("set()  ->", bool(set()))
print("None   ->", bool(None))
print("False  ->", bool(False))

Now the other side. Some values that look empty or false are actually truthy:

Python
print('"hi"  ->', bool("hi"))
print('" "   ->', bool(" "))
print('"0"   ->', bool("0"))
print("-5    ->", bool(-5))
print("[0]   ->", bool([0]))
print("[[]]  ->", bool([[]]))

A single space is text, so it is truthy. The list [0] has one item, so it is truthy even though that item is falsy: Python only asks about the container itself, never about what is inside it.

Shorter conditions

Because an empty collection is falsy, if items: means "if there is anything in items". It does the same job as if len(items) > 0: with less to read, and it works for text, tuples, dictionaries and sets too.

Python
cart = []
if cart:
    print("Items in cart:", len(cart))
else:
    print("Your cart is empty")

cart.append("headphones")
if cart:
    print("Items in cart:", len(cart))

Keep the len() version for when you really need the number ("at least 3 items"). For a plain "is there anything?" check, the short form is what most Python programmers write.

and / or give back one of their operands

Here is the part that surprises people: or and and don't always produce True or False. They hand back one of the two values you wrote.

  • a or b gives a if a is truthy, otherwise b.
  • a and b gives a if a is falsy, otherwise b.

Both stop as soon as the answer is known, so the right-hand side may never even run. Inside an if you only care whether the result is truthy, so you rarely notice. But when you store the result, you get the real value. That is what makes the popular default value trick work: name = entered or "guest".

Python
entered = ""
name = entered or "guest"
print(name)

entered = "Asha"
name = entered or "guest"
print(name)

print("Asha" and "Ben")
print(repr("" and "Ben"))

Pitfall 1: 0 is falsy, even when 0 is a real answer

or can't tell the difference between "no value" and a value that merely happens to be falsy. If 0, 0.0 or "" are legitimate values in your program, or will quietly replace them. When you really mean "nothing was provided", test for None with is None:

Python
score = 0          # the player really scored zero
shown = score or "not played yet"
print(shown)

if score is None:
    shown = "not played yet"
else:
    shown = score
print(shown)

The first version prints the wrong message, because a score of 0 is a real result. The second version only reacts to None, which is Python's way of saying "no value here".

Pitfall 2: the text "False" is truthy

Text is only falsy when it is completely empty. The words "False", "0" and "no" are ordinary non-empty text, so they are all truthy. This catches people out when values come from files, forms or input(), because those always arrive as text. Compare the text itself instead, for example answer.strip().lower() == "yes".

Python
answer = "False"
print(bool(answer))
print(answer == "True")
print(bool(""))

Quick reference: Python Truthy & Falsy

  • How to Check if a List Is Empty in Python — Write `if not my_list:` to check whether a list is empty. An empty list is falsy, so `not my_list` is `True` …
  • Python Set pop() Method — `set.pop()` removes one **arbitrary** element from the set and returns it. On an empty set it raises `KeyErro…
  • Python any() Function — `any(iterable)` returns `True` if **at least one** item of the iterable is truthy, and `False` if none are or…
  • Python all() Function — `all(iterable)` returns `True` if **every** item of the iterable is truthy (or the iterable is empty), and `F…

4Python Truthy & Falsy: syntax

if value:                    # runs when bool(value) is True
if not value:                # runs when value is falsy
bool(value)                  # True or False, using the same rule as if

name = entered or "guest"    # entered if it is truthy, otherwise "guest"
result = a and b             # a if a is falsy, otherwise b

if value is None:            # is there really no value at all?

5Python Truthy & Falsy: run the example

Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.

Interactive example
username = ""
unread = []
balance = 0

print("Has name:", bool(username))
print("Has mail:", bool(unread))

display_name = username or "guest"
print("Welcome,", display_name)

if not unread:
    print("No new messages")

if balance is None:
    print("No account yet")
elif not balance:
    print("Account is empty")
else:
    print("Balance:", balance)
Expected outputHas name: False
Has mail: False
Welcome, guest
No new messages
Account is empty

7Python Truthy & Falsy: how the example works

Hover or tap a step to highlight its lines in the example above.

  1. Line 1-3Three values of different types: empty text, an empty list and the number zero. All three are falsy.
  2. Line 5-6bool() reveals what an if would decide for each value. Both of these print False.
  3. Line 8-9username or "guest": the left side is falsy, so or hands back the right side. display_name becomes "guest".
  4. Line 11-12An empty list is falsy, and not flips that to True, so the condition passes and the message is printed.
  5. Line 14-15is None asks the exact question "is there no account at all?". balance is 0, which is a number, not None, so this branch is skipped.
  6. Line 16-17Now not balance is True because 0 is falsy: the account exists but holds nothing. It is only safe to treat 0 as "empty" here because the None case was already handled above.
  7. Line 18-19The else branch is skipped, since an earlier branch already ran.

8Python Truthy & Falsy: common mistakes

Using or for a default when 0 is a valid value

✗ Wrong

volume = 0
setting = volume or 50
print(setting)
No error, but it prints 50 instead of 0

✓ Right

volume = 0
setting = 50 if volume is None else volume
print(setting)

0 is falsy, so or treats a volume of zero as "missing" and swaps in the default. Test for None explicitly when zero (or empty text) is a legitimate value.

Expecting the text "False" to be falsy

✗ Wrong

answer = "False"
if answer:
    print("Enabled")
else:
    print("Disabled")
No error, but it prints Enabled

✓ Right

answer = "False"
if answer.lower() == "true":
    print("Enabled")
else:
    print("Disabled")

Only an empty string is falsy. "False" is non-empty text, so it counts as True. When a value arrives as text, compare the text itself.

Comparing a collection with == True

✗ Wrong

items = ["pen", "book"]
if items == True:
    print("Has items")
else:
    print("Empty")
No error, but a list with two items prints Empty

✓ Right

items = ["pen", "book"]
if items:
    print("Has items")
else:
    print("Empty")

Truthiness is not equality. A list is never equal to True, even though bool(items) is True. Let the if do the conversion by writing the value on its own.

Checking for None with not

✗ Wrong

discount = 0
if not discount:
    print("No discount has been set")
No error, but it claims no discount was set even though 0 was set on purpose

✓ Right

discount = 0
if discount is None:
    print("No discount has been set")
else:
    print("Discount:", discount)

not discount is True for None, 0, "" and [] alike. If you only want to catch a missing value, write if discount is None:.

9Python Truthy & Falsy: exercises

Write your answer, then press Check. The checks run in your browser.

1. Fall back to a guest name

Write code Easy

username is empty because nobody has signed in. Use or to store in display_name the username when there is one, or the text "guest" when there isn't. Then print Hello, followed by display_name.

Try username = "Asha" to see the other outcome, then set it back to "" and press Check.

Your code
username = ""

# set display_name with or, then print the greeting

2. Predict the truthiness

Predict the output Medium

Read the code and type exactly what it will print. Remember what and and or hand back, and what repr() adds around text. Then press Check to run it and compare.

Read this code
a = [0, 0]
b = ""
c = "0"
d = None
print(bool(a), bool(b), bool(c), bool(d))
print(a and "full")
print(d or b or "fallback")
print(c and 5)
print(repr(b and "never"))

2 more exercises → 5 more examples

Finished this lesson?
Progress is saved in this browser — create a free account to keep it across devices.

Questions learners ask

Is an empty list False in Python?

An empty list is not equal to False, but it is falsy: bool([]) is False, so if my_list: skips its block when the list is empty. The same goes for empty strings, tuples, dictionaries and sets, and for the numbers 0 and 0.0.

Should I write if x == True or just if x?

Write if x:. It is shorter and it also works for values that are not booleans. x == True is a stricter and different test: the number 2 and the text "yes" are truthy, yet neither is equal to True.

What is the difference between `if not x` and `if x is None`?

if not x is True for every falsy value: None, 0, 0.0, empty text, empty collections and False. if x is None is True only for None. Use is None when zero or empty text are acceptable values and you only want to detect that nothing was given.

Further reading

10Next lesson

Up nextPython pass Statementpass is a statement that does nothing; it exists because Python blocks cannot be empty, so you use it to hold the place…

Related:
Python Logical ConditionsPython Shorthand If (Ternary)Python Lists

← Python Shorthand If (Ternary) · All Control Flow lessons · Practise in the IDE