Booleans and truthiness

Beginner25 min

Predict whether any Python object counts as true or false, and choose between ==, is and is None.

What you will learn
  • Predict the truth value of any object
  • Explain the difference between == and is
  • Test for None with is None
  • Negate conditions with not, and know why never to use ~ on a bool
On this page

Every if and while in this module asks a yes-or-no question. Python is generous about what counts as a question: you can hand an if almost any object, not just True or False. This lesson explains the rules, so the next ones can lean on them.

The fundamentals lessons on values and on making decisions cover booleans and boolean logic in general. Here we look at how Python decides.

Booleans are a type

True and False are the two values of the type bool. Comparisons such as 3 < 5 produce them, and bool is a subclass of int, so True behaves like 1 and False like 0 in arithmetic. You saw and, or and their short-circuit behaviour in the operators lesson.

bool_basics.py
print(3 < 5, 3 > 5)
print(True + True)
print(int(False))
Output
True False
2
0

Truthiness

When Python needs a yes or no from something that is not a bool, it uses the object’s truth value. The rule is short:

  • These are falsy: False, None, zero of any numeric type (0, 0.0), and any empty string or collection.
  • Everything else is truthy.

bool(x) shows you the answer for any object. Numbers first:

truthy_numbers.py
print(bool(0), bool(0.0))
print(bool(1), bool(-3))
Output
False False
True True

Now strings. Notice that "0" and " " are truthy: they are non-empty strings, whatever they contain.

truthy_strings.py
print(bool(""))
print(bool("0"), bool(" "), bool("False"))
Output
False
True True True

And None, which always counts as false:

truthy_none.py
print(bool(None), bool(False))
Output
False False

Empty collections are falsy too, while collections with anything inside are truthy. Lists, tuples and dicts arrive in the collections module, so treat this as a preview: [], () and {} are an empty list, tuple and dict.

truthy_collections.py
print(bool([]), bool(()), bool({}))
print(bool([0]), bool([[]]))
Output
False False False
True True

A list holding a falsy item, such as [0], is still non-empty and therefore truthy. Emptiness of the container itself is what counts.

Truthiness lets you write the natural thing. Once you meet if, the test if items: will read as “if there is anything in the list”, and if not text: as “if the string is empty”.

== versus is

== asks whether two objects have equal values. is asks whether they are the very same object in memory. Equal-looking lists show the difference. Lists are a preview again: read the brackets as “a collection of three numbers”.

is_vs_equals.py
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b)
print(a is b)
print(a is c)
Output
True
False
True

a and b hold equal lists but are two separate objects. c is a second name for the object a already points at, which is the name-and-object model from the variables lesson.

Use is for exactly one everyday job: comparing with None. There is only ever one None, so x is None is precise, fast, and cannot be fooled by an object with an unusual ==.

is_none.py
name = None
print(name is None)
print(name is not None)
Output
True
False

The difference between “nothing” and “empty” matters. An empty string is falsy, but it is not None:

missing_vs_empty.py
result = ""
print(result == None, result is None)
print(not result)
Output
False False
True

If something may be “nothing” or “an empty result”, not result treats them alike, while result is None tells them apart.

Negation: not

not x gives True when x is falsy and False otherwise, and it always returns a real bool.

not_operator.py
print(not 0, not "hi")
print(not None)
Output
True False
True

Prefer not to anything cleverer. In particular, do not use the bitwise operator ~ on booleans: ~True is -2, not False, because True is the integer 1. Applying ~ to a bool has been deprecated since Python 3.12 and is scheduled for removal in 3.16, so write not x.

Common pitfalls

  • Treating "0" or "False" as false. Any non-empty string is truthy. Convert the text first, for example text == "0", or int(text).
  • Using truthiness when 0 is a valid value. If count = 0 is a real answer, not count will wrongly treat it as “missing”. Test count is None instead.
  • Comparing with == True. A test such as flag == True is noise, and it is false for 2, which is truthy. Use flag on its own.
  • Using is with numbers and strings. x is 5 may happen to work, but it checks identity, not value, and recent Pythons warn about it with a SyntaxWarning. Use ==.
  • Writing == None. It usually works but is less reliable than is None.
ExerciseTruthiness table

Without running anything, write down bool(x) for each of these seven values: 0, 0.0, -1, "", "False", None, " ". Then check yourself with a single print.

Input: none. Expected output: one line of seven words.

Show solution
truthiness_check.py
print(bool(0), bool(0.0), bool(-1), bool(""), bool("False"), bool(None), bool(" "))
Output
False False True False True False True

Falsy: 0, 0.0, "" and None. Truthy: -1 (any non-zero number), "False" and " " (non-empty strings, whatever they say).

ExerciseMissing versus empty

For each of the three values None, "" and "ok", print one line with two answers: whether the value is None, and whether it is falsy (not value).

Input: none. Expected output:

True True
False True
False False
Show solution
none_vs_falsy.py
value = None
print(value is None, not value)
value = ""
print(value is None, not value)
value = "ok"
print(value is None, not value)
Output
True True
False True
False False

The empty string is falsy but not None, so only the first line says True twice. That is why is None is the right test when “nothing” must be told apart from “empty”.

Summary

  • Falsy values are False, None, numeric zero, and empty strings and collections. Everything else is truthy.
  • == compares values; is compares identity. Use is (and is not) for None.
  • Use not x for negation, never ~x on a bool.

Next: if, elif, else.