GGistDev

Control Flow in Python

Python provides expressive control structures with clear, indentation‑based blocks.

if / elif / else

Conditions use Python’s truthiness rules; only falsy values (False, None, numeric zero, empty containers) are false.

x = 0
if x < 0:
    sign = "negative"
elif x == 0:
    sign = "zero"
else:
    sign = "positive"

Tips:

  • Keep conditions readable; extract complex expressions into named variables
  • Chain comparisons for clarity: 0 <= x < 10
  • Beware of truthy strings like "0" (truthy) vs numeric 0 (falsy)

match (3.10+)

Structural pattern matching replaces long if/elif chains by matching shape and values.

status = 404
match status:
    case 200 | 201:
        kind = "ok"
    case 400:
        kind = "bad_request"
    case 404:
        kind = "not_found"
    case _:
        kind = "other"

Patterns can destructure and guard with conditions.

point = (0, 3)
match point:
    case (0, y):               # x==0, capture y
        axis = "y"
    case (x, 0):
        axis = "x"
    case (x, y) if x == y:     # guard
        axis = "diagonal"
    case _:
        axis = "plane"

Guidelines:

  • Use _ to ignore; prefer explicit cases over large guards
  • Prefer match when branching on variants or shapes

for loops

Iterate over any iterable; prefer enumerate for index+value and zip for parallel iteration.

names = ["Ada", "Guido"]
for i, name in enumerate(names, start=1):
    print(i, name)

for a, b in zip([1,2], ["x","y"]):
    pass

while loops

Loop until a condition changes; ensure progress to avoid infinite loops.

n = 3
while n > 0:
    n -= 1

Use iter(callable, sentinel) to loop until a value is seen without manual while True.

for line in iter(lambda: file.readline().strip(), ""):
    process(line)

Loop control: break, continue, else

  • break exits the loop
  • continue skips to next iteration
  • else runs if the loop wasn’t broken
for n in [1, 3, 5, 8, 9]:
    if n % 2 == 0:
        found = n
        break
else:
    found = None  # runs only if no break occurred

Comprehensions (overview)

Concise transformations with optional filters; prefer for simple one‑liners.

squares = [n*n for n in range(5)]
evencubes = {n: n**3 for n in range(10) if n % 2 == 0}
flat = [x for row in grid for x in row]   # nesting: left-to-right execution

Prefer generator expressions for streaming.

total = sum(n*n for n in range(10))

Ternary expressions

Short conditional expressions; keep branches short.

label = "adult" if age >= 18 else "minor"

Walrus operator (3.8+)

Assign and test in one expression to avoid duplication; use judiciously.

while (line := file.readline()):
    handle(line)

Guard clauses

Return early to keep code flat and readable, especially in error handling.

def parse(text: str) -> int | None:
    if not text:
        return None
    return int(text)

Best practices

  • Prefer for over while when iterating sequences
  • Use enumerate, zip, and comprehensions to express intent
  • Reach for match for value/shape‑based branching; keep patterns simple
  • Use guard clauses and small blocks to reduce nesting

Summary

  • if/elif/else for branching; match for structured patterns
  • for over iterables; break/continue/else to control flow
  • Comprehensions and generators for concise, efficient transformations