Python Fundamentals
Transition to Python to prototype faster with readable, expressive code.
Content
Syntax and Indentation
Versions:
Watch & Learn
AI-discovered learning video
Sign in to watch the learning video for this topic.
Python Syntax and Indentation — The Rules That Make Python Feel Like Poetry
"Whitespace isn't wasted — it's the punctuation of Python." — Probably a TA who drank too much coffee
You're coming into this after installing Python, setting up venv, and playing in the REPL. Nice. You've also seen how C uses braces and semicolons to build structure in programs (hello, Core Data Structures in C). Python takes a different stance: indentation and a few punctuation marks define structure, not braces. That difference is tiny to type but huge to grok. This article explains the rules, the gotchas, and why Python's style both helps and bites you if you're careless.
What this covers and why it matters
- What Python expects for syntax and indentation
- Why Python enforces indentation (spoiler: readability and fewer accidental blocks)
- How to avoid common errors (IndentationError, mixed tabs, wrong nesting)
- Quick comparisons to how C did it, so your brain can connect the dots
Real-life: indentation determines which statements run together. In a web server or data pipeline, a single mis-indented line can change program flow or crash the whole script.
The fundamental rules: what makes Python code valid
1) Statements and blocks
In Python, a colon (:) starts a new block, and the following indented lines belong to that block.
Examples of block starters: if, for, while, def, class, with, try, except, finally.
if x > 0:
print("positive") # indented block
x -= 1
print("done") # outside the block
- The first indented line after the colon defines the block's indentation level
- All lines that belong to the block must have the same indentation
2) Indentation is significant
Unlike C's {} or Java's braces, Python uses indentation to group statements. Mis-indenting is not style — it's syntax.
if ready:
prepare()
launch()
# If `launch()` is less indented, it is not part of the `if`
3) Use spaces, or use tabs — but don't mix them
PEP 8 (Python's style guide) says: use 4 spaces per indentation level. Mixing tabs and spaces can cause an IndentationError even if the code looks aligned.
- Set your editor to insert spaces when you press Tab
- If you inherit a project, run
python -m tabnanny .to find inconsistent indentation
4) Logical lines vs physical lines (continuation)
A single Python statement can span multiple physical lines using:
- Implicit continuation inside parentheses, brackets, or braces
- Explicit continuation with a backslash
\
numbers = [
1, 2, 3,
4, 5,
]
long_string = ("this is a long "
"string split across lines")
result = some_function(a, b, c, d, e,
f, g)
Avoid backslashes when possible — parentheses are safer and prettier.
5) Blank lines and trailing semicolons
- Blank lines are ignored by the interpreter (useful to separate logical sections)
- You may use semicolons to place multiple simple statements on one physical line — but don't. It looks like you mean business, but you actually mean confusion.
x = 1; y = 2 # legal, avoid this unless it's micro-script wizardry
Common errors and how to fix them
IndentationError: unexpected indent
Occurs when indentation appears where none should, for example at the top level:
print("oops") # Unexpected indent at top level
Fix: remove the leading spaces/tabs.
IndentationError: unindent does not match any outer indentation level
Occurs when you change indentation width in the same file or block (e.g., 4 spaces then 3 spaces).
Fix: normalize to 4 spaces (or consistent tab usage). Most editors can convert tabs to spaces.
TabError: inconsistent use of tabs and spaces in indentation
Fix: run a conversion command in your editor or use expand/unexpand tools. In VS Code, enable "Insert Spaces" and set tab size to 4.
Translating from C: a short comparison
In C you'd write:
if (x > 0) {
do_stuff();
}
In Python this becomes:
if x > 0:
do_stuff()
No braces. The indentation is the brace. This is easy until you try to do this:
if (a) {
if (b) {
action();
}
}
Python indentation mirrors this nesting visually — when you forget to indent, you lose nesting.
Real-world insight: when you implemented stacks and queues in C, you used braces to avoid accidental scope mistakes. In Python, your editor and spacing discipline protect you instead.
Examples: control flow, functions, and nested blocks
Function with if/for inside
def process(items):
total = 0
for x in items:
if x % 2 == 0:
total += x
else:
total += x * 2
return total
Notice how return lines up with the for — it's outside the for block but inside the def.
Try/except/finally
try:
risky()
except ValueError as e:
handle(e)
finally:
cleanup()
Each block's indentation is consistent and determined by the colon above it.
Editor tips and tooling
- Configure your editor to use 4 spaces per indent (VS Code, PyCharm, Sublime all support this)
- Turn on visible whitespace to see tabs and spaces
- Use
flake8orpylintto catch style issues early - Use
blackfor automatic formatting if your team agrees — it enforces consistent indentation and line breaks
Pro tip: In CS50's IDE or similar, pressing Tab should insert 4 spaces. If it inserts a real tab, change the setting.
Why people keep misunderstanding this
Because their mental model is anchored in languages with braces. They think indentation is cosmetic. Then they forget a space and Python crashes with an IndentationError, a message that reads like a tiny, judgmental haiku.
Imagine copy-pasting code from the web with mixed tabs. It looks fine visually and then explodes during execution. That's the instant you learn to respect whitespace.
Quick troubleshooting checklist
- If you see an IndentationError, check the preceding lines for a missing or extra indent.
- Use a consistent 4-space indent. Convert tabs to spaces project-wide.
- Check for stray non-printing characters (sometimes from copy/paste) with a hex viewer or by retyping the line.
- Run
python -m pyflakesorflake8to get helpful diagnostics.
Key takeaways
- Python uses indentation to define blocks — it's syntax, not style.
- Always use 4 spaces per level (PEP 8). Do not mix tabs and spaces.
- A missing or inconsistent indent leads to
IndentationErrororTabError— these are fixable and common. - Use your editor and formatters to automate consistency.
"Indent carefully. Python will reward you with readable code and fewer braces to juggle. Or it will loudly complain until you fix your whitespace sins."
If you want, I can:
- Show a side-by-side conversion of a C stack implementation to Python (builds on your C structures)
- Provide a short quiz to test indentation skillz
- Give a tiny VS Code configuration snippet to ensure 4-space inserts
Which one first?
Comments (0)
Please sign in to leave a comment.
No comments yet. Be the first to comment!