Control flow determines which code runs, when it runs, and how many times it runs. Python's control flow tools — conditional statements and loops — follow the same universal concepts covered in the Programming Language Principles series, expressed in Python's clean, indentation-based syntax.
Conditional Statements
Conditional statements execute a block of code only when a specified condition is true.
if Statement
age = 20
if age >= 18:
print("You are an adult.")
The condition does not need parentheses (though they are allowed). The colon : and indentation define the block.
if / else
age = 16
if age >= 18:
print("You are an adult.")
else:
print("You are a minor.")
if / elif / else
Python uses elif (not else if) for additional conditions:
age = 20
if age < 18:
print("Minor")
elif age < 21:
print("Young adult")
elif age < 65:
print("Adult")
else:
print("Senior")
Python evaluates conditions from top to bottom and executes the first block whose condition is True. Once a match is found, the remaining branches are skipped entirely.
Nested if statements
Conditions can be nested inside other conditions:
is_logged_in = True
is_admin = False
if is_logged_in:
if is_admin:
print("Welcome, admin.")
else:
print("Welcome, user.")
else:
print("Please log in.")
Keep nesting shallow where possible — deeply nested conditions are hard to read and are often a signal that the logic should be restructured.
Truthy and Falsy Values
Python evaluates conditions as boolean — any value can be used in a condition, not just explicit True or False. Understanding which values are truthy and which are falsy is essential.
Falsy values in Python
False
None
0 # integer zero
0.0 # float zero
"" # empty string
[] # empty list
{} # empty dictionary
() # empty tuple
set() # empty set
Everything else is truthy. This means you can write:
name = ""
if name:
print(f"Hello, {name}")
else:
print("Name is empty") # This runs — empty string is falsy
This pattern — checking if a value is non-empty without an explicit comparison — is idiomatic Python.
Comparison and Logical Operators in Conditions
Chained comparisons
Python uniquely allows chaining comparison operators — a concise and readable feature:
age = 20
if 18 <= age < 65:
print("Working age")
This is equivalent to age >= 18 and age < 65 but reads more naturally. JavaScript does not support this syntax.
Logical operators
if age >= 18 and has_id:
print("Entry allowed")
if is_weekend or is_holiday:
print("Day off")
if not is_banned:
print("Access granted")
in and not in in conditions
allowed_roles = ["admin", "editor", "moderator"]
role = "editor"
if role in allowed_roles:
print("Access granted")
if role not in ["banned", "suspended"]:
print("Account active")
The Ternary Operator
Python has a one-line conditional expression — the equivalent of JavaScript's ternary operator:
# Syntax: value_if_true if condition else value_if_false
status = "adult" if age >= 18 else "minor"
print(status)
Compare with JavaScript:
const status = age >= 18 ? "adult" : "minor";
Python's syntax reads in a different order — the true value comes first, then the condition, then the false value. Use it for simple, readable one-liners. For complex conditions, a full if/else block is clearer.
match Statement (Python 3.10+)
Python 3.10 introduced structural pattern matching with the match statement — similar to switch in other languages but significantly more powerful:
day = 3
match day:
case 1:
print("Monday")
case 2:
print("Tuesday")
case 3:
print("Wednesday")
case 4 | 5:
print("Thursday or Friday") # Multiple values with |
case _:
print("Weekend") # _ is the default (catch-all)
Matching against strings
command = "quit"
match command:
case "quit":
print("Quitting...")
case "help":
print("Showing help...")
case _:
print(f"Unknown command: {command}")
Matching with conditions (guards)
point = (1, 5)
match point:
case (x, y) if x == y:
print("On the diagonal")
case (x, y):
print(f"Point at {x}, {y}")
match is more expressive than a simple switch. Its full power — matching against complex data structures — is covered in the Python-Specific Features topic.
Loops
Loops repeat a block of code either for a specific number of iterations or while a condition holds.
for Loop
Python's for loop iterates directly over any iterable — a sequence or collection of values. You do not need an index counter unless you explicitly want one.
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
for char in "Wariz":
print(char) # W a r i z (one per line)
range()
To iterate a specific number of times, use range():
for i in range(5):
print(i) # 0, 1, 2, 3, 4
range() accepts up to three arguments:
range(5) # 0, 1, 2, 3, 4
range(2, 8) # 2, 3, 4, 5, 6, 7
range(0, 10, 2) # 0, 2, 4, 6, 8 — step of 2
range(10, 0, -1) # 10, 9, 8, ..., 1 — count down
enumerate() — loop with index
When you need both the index and the value, use enumerate() instead of manually tracking a counter:
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# 0: apple
# 1: banana
# 2: cherry
zip() — loop over multiple sequences
To iterate over two sequences in parallel:
names = ["Wariz", "Ada", "Aliyu"]
scores = [95, 87, 92]
for name, score in zip(names, scores):
print(f"{name}: {score}")
# Wariz: 95
# Ada: 87
# Aliyu: 92
while Loop
Runs as long as the condition remains True:
count = 0
while count < 5:
print(count)
count += 1
Note: Always ensure the condition will eventually become
False. Awhile Trueloop with no exit condition runs forever — an infinite loop. Usebreak(covered below) to exit when needed.
while True with break
A common and intentional pattern for loops that need to run until a specific event occurs:
while True:
user_input = input("Enter 'quit' to exit: ")
if user_input == "quit":
break
print(f"You entered: {user_input}")
Loop Control Statements
break — exit the loop immediately
for i in range(10):
if i == 5:
break
print(i) # 0, 1, 2, 3, 4
continue — skip the current iteration
for i in range(10):
if i % 2 == 0:
continue # Skip even numbers
print(i) # 1, 3, 5, 7, 9
else on loops
Python has a unique feature: loops can have an else clause. The else block runs only if the loop completed without hitting a break:
for i in range(5):
if i == 10:
break
else:
print("Loop completed without break") # This runs
for i in range(5):
if i == 3:
break
else:
print("This will NOT run — loop was broken")
This pattern is useful when searching for something in a loop — the else block runs if the item was not found:
target = 7
numbers = [1, 3, 5, 9, 11]
for n in numbers:
if n == target:
print("Found it!")
break
else:
print("Not found") # Runs because target was never found
pass — the Do-Nothing Statement
pass is a no-op — it does nothing. It exists because Python requires at least one statement in every code block. Use it as a placeholder when you need a block to be syntactically valid but not do anything yet:
if age >= 18:
pass # TODO: implement adult logic
else:
print("Minor")
for item in items:
pass # Placeholder — logic to be added
Summary
| Statement | Purpose |
|---|---|
if / elif / else | Execute code based on conditions |
Ternary x if cond else y | One-line conditional expression |
match / case | Structural pattern matching (Python 3.10+) |
for item in iterable | Iterate over any sequence or collection |
range(start, stop, step) | Generate a numeric sequence for iteration |
enumerate(iterable) | Iterate with both index and value |
zip(a, b) | Iterate over two sequences in parallel |
while condition | Repeat while a condition is true |
break | Exit the loop immediately |
continue | Skip to the next iteration |
else on a loop | Runs if the loop completed without break |
pass | Placeholder — syntactically required but does nothing |