Python Control Structures — if, for, while, and match Explained

Sanjeev SharmaSanjeev Sharma
4 min read

Advertisement

Introduction

Why This Matters

Control structures are the decision-making machinery of every program. They determine which code runs, how many times, and under what conditions. Mastering Python's control flow is non-negotiable — whether you are writing a web API handler, parsing a file, or building an algorithm, you will use if, for, and while constantly.

Python's control structures are deliberately simple and readable. The language relies on indentation instead of curly braces, which enforces clean formatting and eliminates common bugs found in C-style languages. Python 3.10 also introduced structural pattern matching (match/case), bringing powerful branching inspired by functional languages.

Understanding control structures well also helps in technical interviews, where loop invariants, edge cases, and off-by-one errors are common sources of bugs.

Conditional Statements: if / elif / else

score = 78
 
if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
else:
    grade = "F"
 
print(f"Grade: {grade}")  # Grade: C

Ternary (Conditional) Expression

# Single-line conditional assignment
status = "pass" if score >= 60 else "fail"
 
# Nested ternary — use sparingly
label = "high" if score >= 90 else ("mid" if score >= 60 else "low")

for Loops

Python's for loop iterates over any iterable — lists, ranges, strings, dicts, generators.

# Iterate over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)
 
# Range-based loop
for i in range(5):       # 0 to 4
    print(i)
 
for i in range(1, 10, 2):  # 1, 3, 5, 7, 9
    print(i)
 
# Enumerate for index + value
for idx, fruit in enumerate(fruits, start=1):
    print(f"{idx}. {fruit}")
 
# Iterate over dict items
config = {"host": "localhost", "port": 5432}
for key, value in config.items():
    print(f"{key} = {value}")

while Loops

# Count down
count = 5
while count > 0:
    print(count)
    count -= 1
 
# Polling pattern with break
import time
 
attempts = 0
while True:
    result = check_server_status()
    if result == "ready":
        break
    attempts += 1
    if attempts >= 10:
        raise TimeoutError("Server not ready")
    time.sleep(1)

break, continue, and else on Loops

# break: exit the loop early
for num in range(10):
    if num == 5:
        break
    print(num)  # 0 1 2 3 4
 
# continue: skip to next iteration
for num in range(10):
    if num % 2 == 0:
        continue
    print(num)  # 1 3 5 7 9
 
# else on for loop: runs if loop completed without break
for num in range(2, 10):
    for factor in range(2, num):
        if num % factor == 0:
            break
    else:
        print(f"{num} is prime")

match/case — Structural Pattern Matching (Python 3.10+)

command = "quit"
 
match command:
    case "quit":
        print("Exiting...")
    case "help":
        print("Available commands: quit, help, status")
    case "status":
        print("System running")
    case _:
        print(f"Unknown command: {command}")
 
# Match with data structures
point = (0, 1)
 
match point:
    case (0, 0):
        print("Origin")
    case (x, 0):
        print(f"On x-axis at {x}")
    case (0, y):
        print(f"On y-axis at {y}")
    case (x, y):
        print(f"Point at ({x}, {y})")

Nested Control Structures

# Matrix traversal
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
 
for row in matrix:
    for cell in row:
        if cell % 2 == 0:
            print(f"Even: {cell}")
        else:
            print(f"Odd: {cell}")

Common Mistakes

  • Using while True without a break condition — creates an infinite loop
  • Mutating a list while iterating over it — leads to skipped elements or errors
  • Confusing is with == in conditions — is checks identity, == checks equality
  • Forgetting elif and using multiple if statements — all branches evaluate unnecessarily
  • Misusing else on loops — it runs when no break occurred, not when condition is False

Best Practices

  • Use enumerate() instead of manual index tracking in for loops
  • Prefer for item in iterable over for i in range(len(iterable))
  • Use match/case over long if/elif chains when Python 3.10+ is available
  • Keep loop bodies short — extract logic into helper functions if they grow large
  • Add loop limits or timeouts to while True loops in production code

Key Takeaways

  • if/elif/else evaluates conditions top to bottom and stops at the first match
  • Python's for loop iterates over any iterable, not just index ranges
  • range(start, stop, step) is the standard way to loop a fixed number of times
  • break exits the current loop; continue skips to the next iteration
  • The else clause on a loop runs only if no break was encountered
  • match/case (Python 3.10+) supports structural pattern matching on values and shapes
  • Mutating a collection while iterating it causes unpredictable behavior — iterate a copy

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro