Beginner

Control Flow in Python

Learn conditionals, loops, and structural pattern matching in Python with practical Docker-ready examples

Control flow is how a program decides what to do and how many times to do it. Instead of running every line top to bottom, control flow lets your code branch on conditions and repeat work. In Python, this is where the language’s signature feature—significant indentation—really shows itself: there are no curly braces and no end keywords. The structure of your code is its visual layout.

As a multi-paradigm, dynamically typed language, Python keeps control flow approachable. Conditions are plain expressions evaluated for “truthiness,” loops iterate directly over collections rather than fiddling with index counters, and since Python 3.10 there’s match—structural pattern matching that goes well beyond a simple switch statement.

In this tutorial you’ll learn how to branch with if/elif/else, iterate with for and while, control loops with break and continue, write compact conditional expressions, and use the modern match statement. Every example is runnable as-is in a Docker container.

Conditionals: if, elif, else

Python uses if, elif (short for “else if”), and else. A colon ends each condition, and the indented block below it runs when the condition is true. Notice there’s no switch-style ladder needed—elif chains read top to bottom.

Create a file named conditionals.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Branching with if / elif / else
temperature = 72

if temperature > 85:
    print("It's hot outside")
elif temperature >= 60:
    print("The weather is pleasant")
else:
    print("Bring a jacket")

# Python evaluates "truthiness" — empty values are falsy
items = []
if items:
    print(f"You have {len(items)} items")
else:
    print("Your cart is empty")

# Comparison and logical operators combine cleanly
age = 25
has_ticket = True
if age >= 18 and has_ticket:
    print("Entry granted")

# Membership tests read like English
fruit = "apple"
if fruit in ("apple", "banana", "cherry"):
    print(f"{fruit} is in stock")

Empty containers, the number 0, and None are all “falsy” in Python, so if items: is the idiomatic way to ask “is this collection non-empty?” The in operator checks membership directly, replacing the long chains of == comparisons you’d write in many other languages.

For Loops: Iterating Over Sequences

Python’s for loop iterates over the items of a collection, not over a numeric counter. When you do need numbers, range() generates them, and enumerate() gives you both an index and a value.

Create a file named for_loops.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# Iterate directly over a list
languages = ["Python", "Fortran", "Lisp"]
for lang in languages:
    print(f"Exploring {lang}")

# range(start, stop) — stop is exclusive
print("Countdown:")
for n in range(3, 0, -1):
    print(n)

# enumerate gives index + value together
for index, lang in enumerate(languages, start=1):
    print(f"{index}. {lang}")

# Loop over a dictionary's key/value pairs
years = {"Python": 1991, "Fortran": 1957}
for name, year in years.items():
    print(f"{name} first appeared in {year}")

This is one of Python’s most loved features: you rarely write for (i = 0; i < n; i++). You iterate over the thing you actually care about. The for ... else construct also exists, where the else block runs only if the loop finished without hitting break.

While Loops and Loop Control

A while loop repeats as long as its condition stays true. break exits the loop immediately, and continue skips to the next iteration.

Create a file named while_loops.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# A simple while loop
count = 3
while count > 0:
    print(f"T-minus {count}")
    count -= 1
print("Liftoff!")

# break and continue in action
print("Even numbers under 10, skipping 4:")
n = 0
while n < 10:
    n += 1
    if n == 4:
        continue        # skip 4
    if n % 2 != 0:
        continue        # skip odd numbers
    if n > 8:
        break           # stop once we pass 8
    print(n)

continue jumps back to the top of the loop, and break leaves it entirely. Here we increment n first so that continue never accidentally creates an infinite loop—a classic while-loop pitfall worth remembering.

Conditional Expressions and Match

Python offers a compact ternary expression—value_if_true if condition else value_if_false—for inline branching. And since Python 3.10, the match statement provides structural pattern matching for cleanly handling multiple shapes of data.

Create a file named control_flow.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Ternary (conditional) expression
score = 78
grade = "pass" if score >= 60 else "fail"
print(f"Result: {grade}")

# Structural pattern matching (Python 3.10+)
def describe(command):
    match command.split():
        case ["go", direction]:
            return f"Moving {direction}"
        case ["pick", "up", item]:
            return f"Picking up the {item}"
        case ["quit" | "exit"]:
            return "Goodbye!"
        case _:
            return "Unknown command"

print(describe("go north"))
print(describe("pick up sword"))
print(describe("quit"))
print(describe("dance"))

The match statement destructures data as it matches. The case ["go", direction] pattern only matches a two-word list and binds the second word to direction. The | lets one case match several patterns, and case _ is the catch-all wildcard. This is far more powerful than a traditional switch—it matches structure, not just values.

Running with Docker

1
2
3
4
5
6
7
8
# Pull the official image
docker pull python:3.13-alpine

# Run each example
docker run --rm -v $(pwd):/app -w /app python:3.13-alpine python conditionals.py
docker run --rm -v $(pwd):/app -w /app python:3.13-alpine python for_loops.py
docker run --rm -v $(pwd):/app -w /app python:3.13-alpine python while_loops.py
docker run --rm -v $(pwd):/app -w /app python:3.13-alpine python control_flow.py

Expected Output

Running conditionals.py:

The weather is pleasant
Your cart is empty
Entry granted
apple is in stock

Running for_loops.py:

Exploring Python
Exploring Fortran
Exploring Lisp
Countdown:
3
2
1
1. Python
2. Fortran
3. Lisp
Python first appeared in 1991
Fortran first appeared in 1957

Running while_loops.py:

T-minus 3
T-minus 2
T-minus 1
Liftoff!
Even numbers under 10, skipping 4:
2
6
8

Running control_flow.py:

Result: pass
Moving north
Picking up the sword
Goodbye!
Unknown command

Key Concepts

  • Indentation defines blocks — Python has no braces or end keywords; a consistent indent (conventionally four spaces) marks what belongs to each if, for, or while.
  • elif chains replace switch-style ladders, evaluated top to bottom until one condition is true.
  • Truthiness — empty collections, 0, "", and None are falsy, so if items: idiomatically tests for non-emptiness.
  • for iterates over items, not counters; use range() for numbers and enumerate() when you need an index alongside each value.
  • break and continue give you fine control: break exits a loop, continue skips to the next iteration.
  • Ternary expressions (a if cond else b) keep simple branching on a single line.
  • match (3.10+) is structural pattern matching—it destructures and binds data, supports | alternatives, and uses _ as a wildcard, going well beyond a basic switch.

Running Today

All examples can be run using Docker:

docker pull python:3.13-alpine
Last updated:

Comments

Loading comments...

Leave a Comment

2000 characters remaining