On this page
Operators and Control Flow
Operators and Control Flow
Every program needs to make decisions and repeat actions. Control flow is the mechanism that lets your code do different things depending on data — skip steps, repeat work, or choose between alternatives. In this lesson you will learn Python's operator toolkit and all of its control flow constructs, including the modern match/case statement introduced in Python 3.10.
Arithmetic Operators
You have already seen some arithmetic operators. Here is the complete picture:
a, b = 17, 5
print(a + b) # 22 — addition
print(a - b) # 12 — subtraction
print(a * b) # 85 — multiplication
print(a / b) # 3.4 — true division (always float)
print(a // b) # 3 — floor division (integer result, rounds toward -∞)
print(a % b) # 2 — modulo (remainder)
print(a ** b) # 1419857 — exponentiation (17^5)
# Unary operators
print(-a) # -17
print(+a) # 17 (no-op, but valid)
# Augmented assignment (modify in place)
count = 0
count += 1 # count = count + 1
count *= 3 # count = count * 3
count -= 2 # count = count - 2
print(count) # 1Comparison Operators
Comparison operators always return a boolean (True or False):
x, y = 10, 20
print(x == y) # False — equal
print(x != y) # True — not equal
print(x < y) # True — less than
print(x > y) # False — greater than
print(x <= 10) # True — less than or equal
print(x >= 10) # True — greater than or equal
# Python allows chained comparisons — very readable
age = 25
print(18 <= age < 65) # True — much cleaner than age >= 18 and age < 65
score = 85
grade = "B" if 80 <= score < 90 else "other"
print(grade) # BLogical Operators
Python uses the English words and, or, and not instead of symbols like &&, ||, and !:
temperature = 22
is_raining = False
# and — True only if BOTH are True
print(temperature > 20 and not is_raining) # True — nice day!
# or — True if AT LEAST ONE is True
print(temperature < 0 or is_raining) # False
# not — negates the boolean
print(not True) # False
print(not False) # True
# Short-circuit evaluation
# Python stops evaluating as soon as the result is determined
items = []
# This is safe: if items is empty (falsy), Python doesn't evaluate items[0]
first = items and items[0]
print(first) # [] — returns the falsy value (items)
# or returns the first truthy value (or the last value if all are falsy)
default_name = None
name = default_name or "Anonymous"
print(name) # AnonymousBitwise Operators
Less common but useful in certain domains (networking, flags, bit manipulation):
a, b = 0b1010, 0b1100 # 10 and 12 in binary
print(bin(a & b)) # 0b1000 — AND
print(bin(a | b)) # 0b1110 — OR
print(bin(a ^ b)) # 0b0110 — XOR
print(bin(~a)) # -0b1011 — NOT (bitwise complement)
print(bin(a << 1)) # 0b10100 — left shift
print(bin(a >> 1)) # 0b101 — right shiftIdentity and Membership Operators
# Identity — checks if two names point to the same object
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True — same content
print(a is b) # False — different objects in memory
print(a is c) # True — c is just another name for a
# Use `is` only for None, True, False
value = None
print(value is None) # True (correct way)
# Membership — checks if a value is in a sequence
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits) # True
print("mango" not in fruits) # True
text = "Hello, Python!"
print("Python" in text) # True
print("Java" not in text) # TrueThe `if/elif/else` Statement
The if statement is the most fundamental decision-making tool:
def classify_bmi(bmi: float) -> str:
if bmi < 18.5:
return "Underweight"
elif bmi < 25.0:
return "Normal weight"
elif bmi < 30.0:
return "Overweight"
else:
return "Obese"
print(classify_bmi(17.0)) # Underweight
print(classify_bmi(22.5)) # Normal weight
print(classify_bmi(27.3)) # Overweight
print(classify_bmi(35.1)) # ObeseYou can have as many elif branches as you need. The else block is optional. The first condition that evaluates to True runs its block, and the rest are skipped.
Ternary (conditional) expression — a one-liner for simple if/else:
age = 20
status = "adult" if age >= 18 else "minor"
print(status) # adult
# Nested ternary (use sparingly — can hurt readability)
score = 75
grade = "A" if score >= 90 else ("B" if score >= 80 else "C")
print(grade) # CThe `match/case` Statement (Python 3.10+)
match/case is Python's structural pattern matching — far more powerful than a simple switch statement. It can match values, types, shapes, and even destructure data:
def http_status(status_code: int) -> str:
match status_code:
case 200:
return "OK"
case 201:
return "Created"
case 301 | 302: # Pipe operator combines patterns
return "Redirect"
case 400:
return "Bad Request"
case 401 | 403:
return "Authentication/Authorization Error"
case 404:
return "Not Found"
case 500:
return "Internal Server Error"
case _: # Default case (wildcard)
return f"Unknown status: {status_code}"
print(http_status(200)) # OK
print(http_status(404)) # Not Found
print(http_status(418)) # Unknown status: 418match/case with guards (additional conditions):
def describe_point(point: tuple[int, int]) -> str:
match point:
case (0, 0):
return "Origin"
case (x, 0):
return f"On the X-axis at x={x}"
case (0, y):
return f"On the Y-axis at y={y}"
case (x, y) if x == y:
return f"On the diagonal at {x}"
case (x, y):
return f"Point at ({x}, {y})"
print(describe_point((0, 0))) # Origin
print(describe_point((3, 0))) # On the X-axis at x=3
print(describe_point((5, 5))) # On the diagonal at 5
print(describe_point((2, 7))) # Point at (2, 7)tip type: info title: "match/case is not just switch/case"
Unlike switch/case in Java or C, Python's
match/caseperforms structural pattern matching. It can match the shape and content of data structures like tuples, lists, and dictionaries — not just literal values. This makes it especially powerful for parsing commands, protocol messages, or API responses.
The `for` Loop
Python's for loop iterates over any iterable — a list, string, range, dictionary, file, or any object that yields values one at a time:
# Iterating over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit.upper())
# APPLE
# BANANA
# CHERRY
# Iterating over a string
for char in "Python":
print(char, end=" ")
# P y t h o n
# range() generates a sequence of integers
for i in range(5): # 0, 1, 2, 3, 4
print(i, end=" ")
for i in range(1, 11): # 1 through 10
print(i, end=" ")
for i in range(0, 20, 3): # 0, 3, 6, 9, 12, 15, 18 (step 3)
print(i, end=" ")
for i in range(10, 0, -1): # 10 down to 1 (countdown)
print(i, end=" ")enumerate() gives you both the index and the value:
languages = ["Python", "JavaScript", "Rust", "Go"]
for index, language in enumerate(languages, start=1):
print(f"{index}. {language}")
# 1. Python
# 2. JavaScript
# 3. Rust
# 4. Gozip() iterates over multiple iterables in parallel:
names = ["Alice", "Bob", "Carol"]
scores = [92, 85, 78]
for name, score in zip(names, scores):
print(f"{name}: {score}")
# Alice: 92
# Bob: 85
# Carol: 78The `while` Loop
while repeats a block as long as a condition is True:
# Countdown
count = 5
while count > 0:
print(f"T-minus {count}...")
count -= 1
print("Liftoff!")
# Reading input until valid (common pattern)
import random
secret = random.randint(1, 10)
attempts = 0
while True:
guess = int(input("Guess a number (1-10): "))
attempts += 1
if guess == secret:
print(f"Correct! You got it in {attempts} attempt(s).")
break
elif guess < secret:
print("Too low!")
else:
print("Too high!")Loop Control: `break`, `continue`, and `else`
# break — exits the loop immediately
for n in range(1, 20):
if n % 7 == 0:
print(f"First multiple of 7 up to 20: {n}")
break
# continue — skips to the next iteration
print("Odd numbers from 1 to 10:")
for n in range(1, 11):
if n % 2 == 0:
continue # skip even numbers
print(n, end=" ")
# 1 3 5 7 9
# for...else and while...else
# The else block runs ONLY if the loop completed without hitting break
def find_prime(n: int) -> bool:
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
break # factor found — not prime
else:
return True # no break occurred — it's prime
return False
print(find_prime(17)) # True
print(find_prime(18)) # Falsetip type: tip title: "Avoid modifying a list while iterating over it"
Never add or remove elements from a list inside a
for item in my_list:loop — this causes unpredictable skipping of elements. Instead, iterate over a copy (for item in my_list[:]) or build a new list using a list comprehension (covered in Lesson 7).
Nested Loops
# Multiplication table
for i in range(1, 6):
for j in range(1, 6):
print(f"{i * j:3}", end="")
print() # newline after each row
# 1 2 3 4 5
# 2 4 6 8 10
# 3 6 9 12 15
# 4 8 12 16 20
# 5 10 15 20 25`pass` — The No-Op Statement
pass is a statement that does nothing. It is used as a placeholder where Python requires a statement but you have nothing to put there yet:
def future_feature() -> None:
pass # TODO: implement this later
for i in range(10):
if i % 2 == 0:
pass # will handle even numbers later
else:
print(i)nextSteps
- functions-and-scope
Sign in to track your progress