Control Structures
Making decisions and repeating actions with conditionals and loops
Introduction
Control structures allow your programs to make decisions and repeat actions. Conditional statements (if/elif/else) let your code choose different paths based on conditions, while loops (for and while) enable you to execute code repeatedly. Mastering these concepts is essential for writing useful, dynamic programs that can handle different situations and process collections of data.
Conditional Statements: if/elif/else
Conditional statements allow your program to execute different code blocks based on whether conditions are true or false.
Simple if Statement
age = 20
if age >= 18:
print("You are an adult")
print("You can vote")
# Only executes if condition is True
# Note the colon (:) and indentation!if/else Statement
age = 16
if age >= 18:
print("You are an adult")
else:
print("You are a minor")
print("You cannot vote")
# Executes one block or the other, but not bothif/elif/else Statement
Use elif (else if) to check multiple conditions:
score = 85
if score >= 90:
grade = "A"
elif score >= 80:
grade = "B"
elif score >= 70:
grade = "C"
elif score >= 60:
grade = "D"
else:
grade = "F"
print(f"Your grade is {grade}")
# Checks conditions in order
# Stops at first True condition
# Only one block executesNested Conditionals
age = 20
has_license = True
if age >= 18:
if has_license:
print("You can drive")
else:
print("You need a license to drive")
else:
print("You must be 18 to drive")
# Inner if/else inside outer ifMultiple Conditions
temperature = 25
is_sunny = True
# Using and
if temperature > 20 and is_sunny:
print("Perfect weather for a picnic")
# Using or
if temperature < 0 or temperature > 35:
print("Extreme weather conditions")
# Using not
if not is_sunny:
print("It's cloudy today")
# Combining operators
if (temperature >= 15 and temperature <= 25) or is_sunny:
print("Good weather for outdoor activities")Ternary Operator (Conditional Expression)
A concise way to write simple if/else statements:
age = 20
# Traditional way
if age >= 18:
status = "adult"
else:
status = "minor"
# Ternary operator (one line)
status = "adult" if age >= 18 else "minor"
# Syntax: value_if_true if condition else value_if_false
max_value = a if a > b else bImportant Note
Using long chains of if/elif/else statements can lead to code that is hard to read and maintain. In real-world, production-ready programs, there are better patterns and techniques to handle complex decision logic. We will discuss these approaches later in the course!
For Loops
For loops iterate over a sequence (like a list, string, or range) and execute code for each item.
Basic For Loop
# Loop through a list
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
print(fruit)
# Output:
# apple
# banana
# orange
# Loop through a string
for char in "Hello":
print(char)
# Output: H, e, l, l, o (each on new line)Using range()
# range(stop) - 0 to stop-1
for i in range(5):
print(i)
# Output: 0, 1, 2, 3, 4
# range(start, stop) - start to stop-1
for i in range(2, 6):
print(i)
# Output: 2, 3, 4, 5
# range(start, stop, step) - with step size
for i in range(0, 10, 2):
print(i)
# Output: 0, 2, 4, 6, 8
# Countdown
for i in range(5, 0, -1):
print(i)
# Output: 5, 4, 3, 2, 1Looping Through Lists
numbers = [1, 2, 3, 4, 5]
# Loop through values
for num in numbers:
print(num * 2)
# Output: 2, 4, 6, 8, 10
# Loop with index using enumerate()
for index, value in enumerate(numbers):
print(f"Index {index}: {value}")
# Output:
# Index 0: 1
# Index 1: 2
# Index 2: 3
# ...
# Modify list while looping (create new list)
squares = []
for num in numbers:
squares.append(num ** 2)
# squares = [1, 4, 9, 16, 25]Looping Through Dictionaries
person = {"name": "Alice", "age": 30, "city": "New York"}
# Loop through keys (default)
for key in person:
print(key, person[key])
# Output:
# name Alice
# age 30
# city New York
# Loop through keys explicitly
for key in person.keys():
print(key)
# Loop through values
for value in person.values():
print(value)
# Loop through key-value pairs
for key, value in person.items():
print(f"{key}: {value}")
# Output:
# name: Alice
# age: 30
# city: New YorkNested For Loops
# Multiplication table
for i in range(1, 4):
for j in range(1, 4):
print(f"{i} x {j} = {i * j}")
print() # Blank line between tables
# Loop through 2D list
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for row in matrix:
for value in row:
print(value, end=" ")
print() # New line after each row
# Output:
# 1 2 3
# 4 5 6
# 7 8 9- If you find yourself writing loops inside loops inside loops (three or more levels), consider refactoring your code.
- Look for alternatives like breaking code into functions, using helper data structures, or leveraging built-in functions such as
zip(),enumerate(),itertoolsutilities, or comprehensions. - Sometimes, complex problems can be solved more elegantly by flattening data or by using recursion or external libraries.
# Discouraged: Triple nested for-loops
for a in A:
for b in B:
for c in C:
# ...do something with combination of a, b, and c...
pass
# Better: Use itertools.product to avoid nested loops.
from itertools import product
def process(a, b, c):
# ...do something...
pass
for a, b, c in product(A, B, C):
process(a, b, c)
While Loops
While loops continue executing as long as a condition is True. They're useful when you don't know beforehand how many iterations you need.
Basic While Loop
# Count from 1 to 5
count = 1
while count <= 5:
print(count)
count += 1 # Increment counter (important!)
# Output: 1, 2, 3, 4, 5
# Sum numbers until user enters 0
total = 0
num = int(input("Enter a number (0 to stop): "))
while num != 0:
total += num
num = int(input("Enter a number (0 to stop): "))
print(f"Total: {total}")Infinite Loops
Warning: Be careful with while loops! If the condition never becomes False, you'll create an infinite loop. Always ensure the condition will eventually become False, or use break to exit.
# This creates an infinite loop (DON'T RUN!)
# count = 1
# while count > 0:
# print(count)
# count += 1 # Condition never becomes False!
# Correct: condition eventually becomes False
count = 5
while count > 0:
print(count)
count -= 1 # Decrement - condition will become FalseWhile vs For Loop
Use While Loop When:
- You don't know iterations in advance
- Looping until a condition is met
- User input validation
- Processing until sentinel value
- Event-driven loops
Use For Loop When:
- Iterating over a sequence
- Known number of iterations
- Processing all items in collection
- More readable for sequences
- Pythonic way for collections
Break and Continue Statements
break and continue give you more control over loop execution.
Break Statement
break exits the loop immediately, even if the condition is still True:
# Find first even number
numbers = [1, 3, 5, 8, 9, 10]
for num in numbers:
if num % 2 == 0:
print(f"First even number: {num}")
break # Exit loop immediately
print(f"{num} is odd")
# Output:
# 1 is odd
# 3 is odd
# 5 is odd
# First even number: 8
# (Loop stops here, doesn't check 9 or 10)
# Break in while loop
while True:
user_input = input("Enter 'quit' to exit: ")
if user_input.lower() == 'quit':
break # Exit infinite loop
print(f"You entered: {user_input}")Continue Statement
continue skips the rest of the current iteration and moves to the next:
# Print only even numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
for num in numbers:
if num % 2 != 0: # If odd
continue # Skip to next iteration
print(num)
# Output: 2, 4, 6, 8
# (1, 3, 5, 7 are skipped)
# Skip negative numbers
numbers = [5, -2, 8, -1, 9]
for num in numbers:
if num < 0:
continue
print(f"Processing {num}")
# Only processes: 5, 8, 9Else Clause with Loops
You can use else with loops. The else block executes only if the loop completes normally (not exited with break):
# Search for a value
numbers = [1, 3, 5, 7, 9]
search_for = 4
for num in numbers:
if num == search_for:
print(f"Found {search_for}!")
break
else:
# Executes only if loop completes without break
print(f"{search_for} not found in list")
# If search_for = 5, prints "Found 5!" and else doesn't execute
# If search_for = 4, prints "4 not found in list"Looping Through Data Structures
Here are comprehensive examples of looping through different data structures:
Lists
fruits = ["apple", "banana", "orange"]
# Simple iteration
for fruit in fruits:
print(fruit.upper())
# With index
for i, fruit in enumerate(fruits):
print(f"{i+1}. {fruit}")
# With condition
for fruit in fruits:
if len(fruit) > 5:
print(f"{fruit} has more than 5 characters")Tuples
coordinates = [(0, 0), (1, 2), (3, 4), (5, 6)]
# Unpacking during iteration
for x, y in coordinates:
print(f"Point at ({x}, {y})")
# With index
for i, (x, y) in enumerate(coordinates):
distance = (x**2 + y**2)**0.5
print(f"Point {i}: ({x}, {y}), distance from origin: {distance:.2f}")Dictionaries
student_grades = {
"Alice": 85,
"Bob": 92,
"Charlie": 78,
"Diana": 95
}
# Loop through keys
for name in student_grades:
print(name, student_grades[name])
# Loop through items (key-value pairs) - recommended
for name, grade in student_grades.items():
status = "Pass" if grade >= 80 else "Fail"
print(f"{name}: {grade} ({status})")
# Loop through values only
total = 0
for grade in student_grades.values():
total += grade
average = total / len(student_grades)
print(f"Average grade: {average}")Sets
unique_numbers = {1, 2, 3, 4, 5}
# Simple iteration (order not guaranteed)
for num in unique_numbers:
print(num ** 2)
# Process only even numbers
for num in unique_numbers:
if num % 2 == 0:
print(f"{num} is even")Nested Structures
# List of dictionaries
students = [
{"name": "Alice", "grades": [85, 90, 88]},
{"name": "Bob", "grades": [78, 82, 80]},
{"name": "Charlie", "grades": [92, 95, 93]}
]
for student in students:
name = student["name"]
grades = student["grades"]
average = sum(grades) / len(grades)
print(f"{name}'s average: {average:.1f}")
# Dictionary with list values
data = {
"fruits": ["apple", "banana"],
"vegetables": ["carrot", "broccoli"],
"grains": ["rice", "wheat"],
}
for category, items in data.items():
print(f"{category}: {', '.join(items)}")Practical Examples
Example: Number Guessing Game
import random
secret_number = random.randint(1, 100)
max_attempts = 5
attempts = 0
print("I'm thinking of a number between 1 and 100.")
print(f"You have {max_attempts} attempts.")
while attempts < max_attempts:
guess = int(input("Enter your guess: "))
attempts += 1
if guess == secret_number:
print(f"Congratulations! You guessed it in {attempts} attempts!")
break
elif guess < secret_number:
print("Too low!")
else:
print("Too high!")
remaining = max_attempts - attempts
if remaining > 0:
print(f"You have {remaining} attempts remaining.")
else:
print(f"Game over! The number was {secret_number}.")Example: Data Processing
# Process student data
students = {
"Alice": [85, 90, 88],
"Bob": [78, 82, 80],
"Charlie": [92, 95, 93],
"Diana": [65, 70, 68]
}
# Calculate statistics
for name, grades in students.items():
average = sum(grades) / len(grades)
max_grade = max(grades)
min_grade = min(grades)
print(f"\n{name}:")
print(f" Average: {average:.1f}")
print(f" Highest: {max_grade}")
print(f" Lowest: {min_grade}")
# Determine grade letter
if average >= 90:
letter = "A"
elif average >= 80:
letter = "B"
elif average >= 70:
letter = "C"
else:
letter = "F"
print(f" Letter Grade: {letter}")Key Takeaways
Conditionals
- Use
if/elif/elsefor decisions - Combine conditions with
and,or,not - Nest conditionals for complex logic
- Ternary operator for simple assignments
Loops
- Use
forfor sequences - Use
whilefor unknown iterations range()generates number sequencesenumerate()gets index and value
Control Flow
breakexits loop immediatelycontinueskips to next iterationelsewith loops runs if no break
Best Practices
- Prefer
foroverwhilewhen possible - Use
enumerate()when you need index - Use
.items()for dictionary loops - Avoid infinite loops in
while
What's Next?
Excellent work! You now know how to control program flow with conditionals and loops. Next, we'll learn about functions, one of the most important concepts in programming:
- Defining and calling functions - Create reusable blocks of code
- Parameters and arguments - Pass data into your functions
- Return values - Get results back from functions
- Scope and variables - Understand local vs global scope
- Lambda functions - Write compact, anonymous functions