Skip to content

Control Flow

Python’s conditional statements are the most basic form of control flow. Unlike many languages, Python uses indentation rather than braces or keywords to delimit blocks.

def classify_temperature(temp_celsius: float) -> str:
if temp_celsius < 0:
return "freezing"
elif temp_celsius < 15:
return "cold"
elif temp_celsius < 25:
return "comfortable"
elif temp_celsius < 35:
return "warm"
else:
return "hot"

The condition expression can be any Python object. Python evaluates its truthiness using the __bool__() protocol described in the previous chapter. There is no requirement that the condition Be a boolean — this is consistent with Python’s broader philosophy of duck typing.

## All of these are valid conditional expressions
if [1, 2, 3]:
print("non-empty list is truthy")
if "":
print("this never executes")
if not None:
print("None is falsy, so not None is truthy")

This is one of Python’s most controversial design decisions and the source of the most frequent Criticism from programmers coming from brace-delimited languages. The rationale is both Philosophical and practical:

  1. Eliminates a class of bugs. In C-style languages, mismatched braces are a persistent source of errors. The compiler cannot detect whether the indentation reflects the programmer’s intent because the braces define the actual structure. Python makes the indentation the structure — what you see is what the interpreter sees.

  2. Enforces a single canonical style. Every Python program has consistent block structure. There is no debate over K&R versus Allman versus GNU indentation style because there is no choice. This reduces cognitive overhead in code reviews and eliminates formatting arguments.

  3. Reduces visual noise. Braces, semicolons, and explicit block terminators are syntactic overhead that provides no semantic information beyond what indentation already conveys. Removing them makes code more compact without sacrificing readability.

  4. Historical precedent. Guido van Rossum was influenced by ABC (a teaching language developed at CWI) and Haskell, both of which use indentation-based syntax. The choice was deliberate, not accidental.

The trade-off is sensitivity to whitespace. Mixing tabs and spaces, or inconsistent indentation, Causes IndentationError. Python 3 disallows mixing tabs and spaces entirely within the same file. PEP 8 mandates 4 spaces per indentation level.