You've learned how to make your programs execute code conditionally using if
, elif
, and else
, and how to repeat actions using while
and for
loops. The real power comes when you combine these structures. You can place control flow statements inside other control flow statements. This technique is called nesting, and it allows you to build more sophisticated logic into your programs.
Imagine you need to check multiple conditions before performing an action, or you need to perform a repetitive task for each item processed in another repetition. Nesting makes this possible.
You can place an if
, elif
, or else
statement inside another if
, elif
, or else
block. This allows you to check for secondary conditions only if a primary condition is met.
Consider a scenario where you need to check if a person is eligible for a specific discount: they must be a student and have a valid ID.
is_student = True
has_valid_id = False
age = 20
print("Checking discount eligibility...")
if age < 25: # Outer condition: Age check
print("Age requirement met.")
if is_student: # Inner condition 1: Student status
print("Student status confirmed.")
if has_valid_id: # Inner condition 2: ID check
print("Valid ID confirmed.")
print("Congratulations! You are eligible for the discount.")
else: # Inner else (belongs to ID check)
print("Valid ID not found. Discount not applicable.")
else: # Inner else (belongs to student status check)
print("Not a student. Discount not applicable.")
else: # Outer else (belongs to age check)
print("Age requirement not met. Discount not applicable.")
print("Eligibility check complete.")
Notice the indentation. The inner if
/else
blocks are indented further than the outer if
/else
block. Python uses this indentation to understand which statements belong to which block. The inner checks (student status, valid ID) are only performed if the preceding outer condition (age < 25
) evaluates to True
.
Loops can also be nested. A common use case is iterating over multi-dimensional data structures (like grids or tables) or processing combinations of items from different sequences.
for
LoopsLet's say you want to print all possible coordinate pairs (x, y) for a small 3x2 grid (where x goes from 0 to 2, and y goes from 0 to 1).
print("Generating grid coordinates:")
# Outer loop iterates through x values
for x in range(3): # x will be 0, 1, 2
# Inner loop iterates through y values for EACH x
for y in range(2): # y will be 0, 1
print(f" ({x}, {y})") # Print the coordinate pair
print("Coordinate generation finished.")
Output:
Generating grid coordinates:
(0, 0)
(0, 1)
(1, 0)
(1, 1)
(2, 0)
(2, 1)
Coordinate generation finished.
Here's how it executes:
x = 0
.x = 0
. It iterates with y = 0
, then y = 1
, printing (0, 0)
and (0, 1)
.x = 0
.x = 1
.x = 1
. It iterates with y = 0
, then y = 1
, printing (1, 0)
and (1, 1)
.x = 1
.x = 2
.x = 2
, printing (2, 0)
and (2, 1)
.The inner loop completes all its iterations for each single iteration of the outer loop.
while
LoopsYou can nest while
loops too, although it requires careful management of the loop conditions to avoid infinite loops.
outer_count = 0
print("Outer loop starting...")
while outer_count < 2:
print(f"Outer loop iteration {outer_count}")
inner_count = 0
# Inner loop runs while inner_count < 3
while inner_count < 3:
print(f" Inner loop iteration {inner_count}")
inner_count += 1 # Crucial: update inner loop variable
outer_count += 1 # Crucial: update outer loop variable
print("Outer loop finished.")
Output:
Outer loop starting...
Outer loop iteration 0
Inner loop iteration 0
Inner loop iteration 1
Inner loop iteration 2
Outer loop iteration 1
Inner loop iteration 0
Inner loop iteration 1
Inner loop iteration 2
Outer loop finished.
Just like with nested for
loops, the inner while
loop runs to completion for each iteration of the outer while
loop. Ensure that the conditions for both loops will eventually become False
.
One of the most frequent patterns is nesting conditional statements inside loops, or vice versa.
if
Statements Inside LoopsThis is extremely common. You iterate through a sequence and perform an action only if a certain condition is met for an item.
Example: Print only the even numbers from a list.
numbers = [11, 22, 37, 44, 58, 61, 76]
print("Even numbers found:")
for num in numbers:
# Check the condition for each number in the list
if num % 2 == 0: # Is the number divisible by 2?
print(f" {num}")
print("Search complete.")
Output:
Even numbers found:
22
44
58
76
Search complete.
The for
loop iterates through each num
in the numbers
list. Inside the loop, the if
statement checks if the current num
is even. Only if the condition num % 2 == 0
is true does the print()
statement execute.
if
StatementsYou might want to execute a loop only if a certain condition is true.
Example: If a list is not empty, print its contents.
data = ["apple", "banana", "cherry"]
# data = [] # Try uncommenting this line to see the difference
if data: # Checks if the list is not empty (non-empty lists are True-like)
print("Processing data items:")
for item in data:
print(f" - {item}")
else:
print("No data items to process.")
Output (with the original data
list):
Processing data items:
- apple
- banana
- cherry
Output (if data = []
is uncommented):
No data items to process.
Here, the for
loop is nested inside the if
block. It only runs if the initial if data:
check passes (meaning the list is not empty).
Remember, Python uses indentation to define code blocks. With nested structures, correct indentation is absolutely essential. Each level of nesting requires an additional level of indentation (typically 4 spaces). Incorrect indentation will lead to IndentationError
or, worse, code that runs but produces incorrect results because the logic is not interpreted as you intended.
# Correct Indentation
for i in range(2):
print(f"Outer {i}")
if i == 0:
print(" Inner check for i=0") # Indented under if
for j in range(2):
print(f" Inner loop {j}") # Indented under inner for
# Incorrect Indentation (will likely cause errors or wrong logic)
# for i in range(2):
# print(f"Outer {i}") # Error: Expected an indented block
# if i == 0:
# print(" Inner check for i=0")
# for j in range(2):
# print(f" Inner loop {j}") # Error or wrong scope
While nesting is powerful, deeply nested structures (e.g., a loop inside a loop inside an if
inside another loop) can become very difficult to read and understand. Generally, try to limit nesting to two or three levels. If you find yourself needing deeper nesting, consider if you can break down the logic into smaller, separate functions (which you'll learn about in Chapter 5).
Nesting control structures allows you to create complex program flows by combining simple if
, while
, and for
statements. Mastering nesting and paying close attention to indentation are significant steps in writing effective Python code.
© 2025 ApX Machine Learning