Loops and Indentation
Indentation is required syntax in Python, not optional formatting. Leading whitespace determines how statements are grouped into blocks.
Try it: Syntax Errors and Indentation
How Python checks a program's structure before running any of it: the tokenizer tracks indentation with a stack (INDENT and DEDENT), the parser groups lines into blocks after each colon, and when something is wrong Python reports the exact SyntaxError, IndentationError or TabError with the line, a caret under the spot and hints like "Did you mean '=='".
How it works
- The tokenizer reads each line's leading spaces: deeper than the top of the indentation stack is an INDENT (pushed), shallower pops DEDENTs until it matches, and a width that matches no open level is an IndentationError.
- Tabs count as 8 columns and as 1; if the two ways of counting disagree about the block structure, it is a TabError.
- Inside ( [ { line breaks and indentation are ignored, so a missing ) swallows the following lines; Python reports "'(' was never closed" when the error is found on a later line.
- The parser matches statements: a header such as if, for, while, def or else must end with ':' and be followed by an indented block; = where a condition is expected, or a keyword used as a name, is invalid syntax.
- Python stops at the first error and prints File, line, the source line, a caret (^) under the columns it blames, and the error type and message; no line of the program has run.
Default run (4 steps): main.py has 7 lines. Before running any of it, Python compiles the whole file: the tokenizer splits each line into tokens and tracks indentation, and the parser groups the statements into blocks. … Python stops: SyntaxError: expected ':' (line 2). No line of the program has run.
Simplified: The programs are fixed and you break them with one menu choice at a time. The lab's own small Python tokenizer and parser (written for the statements these programs use: assignments, print calls, if / elif / else, for, while, def and return) checks the text; nothing is executed as real Python. Every program the lab can show was compiled by CPython 3.12 and the lab reproduces its exception type, message, line, caret columns and the printed report. Only the error kinds offered in the menu are modelled.
Loading the simulation…
Why Whitespace Carries Meaning
In many languages, spaces at the start of a line are only a matter of style. Python is different. Indentation is required syntax, not optional formatting. The amount of leading whitespace on a line tells Python how that line relates to the lines around it. A loop is a good place to see this, because the statements that should repeat must be grouped together, and indentation is how that grouping is written down.
Keep one question in mind as you read: when Python reaches a line, how does it know whether that line belongs to the loop or comes after it? The answer, as the rest of this article shows, is the leading whitespace.
Tracing a Loop Body Line by Line
Read the program below and trace it as Python would. The loop header ends with a colon. The line that follows, indented further, is the loop body. Python runs that body once for each item in the list. The final line is not indented at all, so it is not part of the loop.
1
2
3
done- The for line starts the loop and ends with a colon
- The indented
print(n)is the loop body and runs once per item - The unindented
print("done")is outside the loop and runs once, after the loop finishes
What do you think happens?
Before reading the output, what do you think this program prints, and how many times does print(n) run?
Reveal answer
1, 2, 3, then done
The indented print(n) runs once for each of the three items, so it prints 1, 2, and 3. The unindented print("done") runs once after the loop has finished, so the output ends with done. Only the indented line repeats.
Reading Blocks from Leading Whitespace
A block is a group of statements that Python treats as one unit. In Python, leading whitespace determines how statements are grouped into blocks. Statements at the same indentation level belong to the same block. A statement with more indentation than the line before it starts a new, deeper block.
Notice what the diagram shows. Nothing in the code says repeat or stop. The only thing separating the loop body from the statement after the loop is how far each line is indented. When the indentation returns to the level of the for line, the block has ended.
What runs on each pass through the loop, and when does control leave the indented block?
The indented body runs once for each item. Each pass uses the next value of n. When the items run out, Python leaves the indented block and continues with the first unindented line that follows it.
Recognizing and Fixing an IndentationError
An IndentationError occurs when Python finds indentation where it does not expect it, or when indentation is inconsistent. You cannot start a new block whenever you like. A block opened by a line ending in a colon must be followed by an indented body. The before and after versions below show the most common case: the body is missing its indentation.
for n in [1, 2, 3]:
print(n)The for line ends with a colon, but the next line is not indented, so Python finds no block body. This raises an IndentationError.
for n in [1, 2, 3]:
print(n)The print line is indented one level under the for line. The block is complete, and the program runs, printing 1, 2, and 3.
When you see an IndentationError, check three things in order: whether the line after a colon is indented, whether lines that belong to the same block have the same amount of leading whitespace, and whether the file mixes tabs with spaces. Mixing tabs and spaces is a named cause of indentation errors, so the fix is to use one kind of indentation throughout the file.
Choosing Four Spaces Per Level
The official Python standard is four spaces per indentation level. Every example in this article follows that rule. The standard exists so that code written by different people looks the same, and so that the visual hierarchy of nested blocks is easy to read at a glance.
Consistency is the critical part. The number four is the agreed standard, but what makes indentation work is using the same amount, with the same kind of character, at each level. Mixing spaces and tabs, or using an inconsistent number of spaces, causes errors.
Required Versus Optional Indentation
Indentation is required wherever Python expects a block. After a loop header or an if header, the body must be indented. Within a block, every statement at the same level must line up. Where indentation changes block structure, it is syntax, and getting it wrong raises an error or silently changes the program.
| Situation | What indentation does | What to do |
|---|---|---|
| Line after a loop or if header | Starts the block body; required | Indent the body, consistently |
| Statement at the same level as the loop | Ends the loop body; changes meaning | Align with the header only when it should run after the loop |
| Nested block inside another | Defines a deeper level; required | Add one consistent level per nesting step |
| Mixing tabs and spaces within a file | Causes errors | Use one kind of indentation throughout |
Where indentation is structural and where its mistakes show up
Practice Tracing Nested Blocks
Without running the code, predict the output of the program below. Then check which lines are inside the loop body and which run after it, using only the leading whitespace.
items = [4, 7]
for x in items:
if x > 5:
print("big")
print(x)
print("finished")Hints
- Find the for line and the lines indented under it first
- The if statement has its own body, indented one level further
- The
print(x)line is at the same level as the if line, so it runs for every item
Take the broken loop from the IndentationError section and write a corrected version that prints each item and then prints finished after the loop. Use four spaces for every indentation level.
Hints
- Indent only the lines that belong to the loop body
- Leave the final print unindented
Key Takeaways
- Leading whitespace determines how statements are grouped into blocks, and indentation is required syntax in Python.
- A loop body is the indented block that runs once per item; the first unindented line after it runs after the loop finishes.
- An
IndentationErrorappears when indentation is missing where a block is expected, or when it is inconsistent or mixes tabs and spaces. - The official standard is four spaces per level, and consistency matters more than any single number.
- Nested blocks each add one more level of indentation, and each statement belongs to the nearest block above it with less indentation.