Booleans and truthiness
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.
print(3 < 5, 3 > 5)print(True + True)print(int(False))True False20Truthiness
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:
print(bool(0), bool(0.0))print(bool(1), bool(-3))False FalseTrue TrueNow strings. Notice that "0" and " " are truthy: they are non-empty strings, whatever they contain.
print(bool(""))print(bool("0"), bool(" "), bool("False"))FalseTrue True TrueAnd None, which always counts as false:
print(bool(None), bool(False))False FalseEmpty 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.
print(bool([]), bool(()), bool({}))print(bool([0]), bool([[]]))False False FalseTrue TrueA 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”.
a = [1, 2, 3]b = [1, 2, 3]c = a
print(a == b)print(a is b)print(a is c)TrueFalseTruea 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 ==.
name = Noneprint(name is None)print(name is not None)TrueFalseThe difference between “nothing” and “empty” matters. An empty string is falsy, but it is not None:
result = ""print(result == None, result is None)print(not result)False FalseTrueIf 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.
print(not 0, not "hi")print(not None)True FalseTruePrefer 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 exampletext == "0", orint(text). - Using truthiness when
0is a valid value. Ifcount = 0is a real answer,not countwill wrongly treat it as “missing”. Testcount is Noneinstead. - Comparing with
== True. A test such asflag == Trueis noise, and it is false for2, which is truthy. Useflagon its own. - Using
iswith numbers and strings.x is 5may happen to work, but it checks identity, not value, and recent Pythons warn about it with aSyntaxWarning. Use==. - Writing
== None. It usually works but is less reliable thanis None.
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
print(bool(0), bool(0.0), bool(-1), bool(""), bool("False"), bool(None), bool(" "))False False True False True False TrueFalsy: 0, 0.0, "" and None. Truthy: -1 (any non-zero number), "False" and " " (non-empty strings, whatever they say).
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 TrueFalse TrueFalse FalseShow solution
value = Noneprint(value is None, not value)
value = ""print(value is None, not value)
value = "ok"print(value is None, not value)True TrueFalse TrueFalse FalseThe 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;iscompares identity. Useis(andis not) forNone.- Use
not xfor negation, never~xon a bool.
Next: if, elif, else.