Conditional Statements
Python uses if, elif, and else for conditional branching. Unlike many languages, Python does not have a switch/case statement in older versions, but Python 3.10 introduced structural pattern matching with match/case.
# Basic if/elif/else
temperature = 35
if temperature > 30:
print("It's hot outside!")
elif temperature > 20:
print("Nice weather!")
elif temperature > 10:
print("A bit chilly")
else:
print("It's cold!")
# Conditional expressions (ternary operator)
age = 20
status = "adult" if age >= 18 else "minor"
print(status) # "adult"
# Chained comparisons (Pythonic!)
x = 15
if 10 < x < 20:
print("x is between 10 and 20")
# Multiple conditions
score = 85
has_bonus = True
if score >= 80 and has_bonus:
print("You passed with distinction!")
# Truthy/falsy in conditions
items = [1, 2, 3]
if items: # Non-empty list is truthy
print(f"List has {len(items)} items")
name = ""
if not name: # Empty string is falsy
print("Name is empty")
For Loops
Python's for loop iterates over any iterable object — lists, strings, tuples, dictionaries, ranges, files, and more. It is fundamentally different from C-style for loops; think of it as a "for each" loop.
# Iterating over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# range() for numeric iteration
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(2, 10, 3): # 2, 5, 8 (start, stop, step)
print(i)
# enumerate() - get index and value
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# Iterating over a dictionary
scores = {"Alice": 95, "Bob": 87, "Charlie": 92}
for name, score in scores.items():
print(f"{name}: {score}")
for key in scores: # iterates over keys by default
print(key)
for value in scores.values(): # iterate over values
print(value)
# zip() - iterate over multiple iterables in parallel
names = ["Alice", "Bob", "Charlie"]
ages = [30, 25, 35]
for name, age in zip(names, ages):
print(f"{name} is {age}")
# Nested loops
for i in range(3):
for j in range(3):
print(f"({i}, {j})", end=" ")
print()
While Loops
The while loop repeats as long as a condition is true. Use it when you do not know in advance how many iterations you need. Always ensure there is a way for the condition to become false, otherwise you create an infinite loop.
# Basic while loop
count = 0
while count < 5:
print(count)
count += 1
# While with user input
# while True:
# user_input = input("Enter 'quit' to exit: ")
# if user_input == "quit":
# break
# print(f"You entered: {user_input}")
# While with else (executes if loop completes without break)
n = 10
while n > 0:
n -= 1
if n == 5:
continue # skip 5
print(n)
else:
print("Loop completed normally")
# Practical example: binary search
def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
sorted_list = [1, 3, 5, 7, 9, 11, 13]
print(binary_search(sorted_list, 7)) # 3
Break, Continue, and Else
break exits the current loop entirely. continue skips the rest of the current iteration and moves to the next one. Python uniquely supports an else clause on loops, which executes only if the loop completes without hitting a break.
# break - exit the loop
for n in range(100):
if n > 5:
break
print(n) # 0, 1, 2, 3, 4, 5
# continue - skip current iteration
for n in range(10):
if n % 2 == 0:
continue
print(n) # 1, 3, 5, 7, 9
# for/else - else runs only if no break occurred
def find_prime_factor(n):
for i in range(2, n):
if n % i == 0:
print(f"First factor of {n} is {i}")
break
else:
print(f"{n} is prime!")
find_prime_factor(17) # "17 is prime!"
find_prime_factor(15) # "First factor of 15 is 3"
Structural Pattern Matching (Python 3.10+)
Python 3.10 introduced match/case statements, which are far more powerful than simple switch/case. They support destructuring, guards, type matching, and complex patterns.
# Basic pattern matching
def handle_command(command):
match command.split():
case ["quit"]:
print("Quitting...")
case ["go", direction]:
print(f"Going {direction}")
case ["get", item] if item != "sword":
print(f"Picking up {item}")
case ["get", "sword"]:
print("The sword is too heavy!")
case _:
print(f"Unknown command: {command}")
handle_command("go north") # Going north
handle_command("get shield") # Picking up shield
handle_command("get sword") # The sword is too heavy!
# Pattern matching with types
def process_value(value):
match value:
case int(n) if n > 0:
print(f"Positive integer: {n}")
case int(n):
print(f"Non-positive integer: {n}")
case str(s):
print(f"String: {s}")
case [x, y]:
print(f"Two-element list: {x}, {y}")
case {"name": name, "age": age}:
print(f"Person: {name}, age {age}")
case _:
print("Something else")
process_value(42) # Positive integer: 42
process_value("hello") # String: hello
process_value([1, 2]) # Two-element list: 1, 2
process_value({"name": "Alice", "age": 30}) # Person: Alice, age 30
Key Takeaways
- Chained comparisons: Use
10 < x < 20instead ofx > 10 and x < 20 - for/else: The else block runs when the loop exits without break
- Prefer for over while: Use for loops when iterating over sequences
- Pattern matching: Use match/case for complex conditional logic in Python 3.10+