So far, we've explored how to make decisions using if, elif, and else statements, and how to repeat actions with for and while loops. Now, let's combine these powerful tools to create more complex and dynamic programs. This is where nested control flow comes into play – essentially, putting control flow statements inside other control flow statements.
Imagine you need to check if a student passed a course, and if they did, then check if they achieved a certain grade to qualify for honors. This involves a decision within another decision. Or, consider iterating through a list of students and, for each student, iterating through their list of assignments to check if they're all completed. This is a loop within a loop.
Nesting allows us to build sophisticated logic. The key is that the inner control flow statement executes entirely for each iteration or condition of the outer one. Let's start with nesting if statements.
grade = 85
aplicable_for_honors = False
if grade >= 70:
print("Student passed the course.")
if grade >= 90:
print("Student achieved honors!")
aplicable_for_honors = True
else:
print("Student did not pass the course.")
if aplicable_for_honors:
print("Proceed with honors application.")In this example, the inner if grade >= 90: statement is only checked if the outer condition grade >= 70 is true. This is a clear demonstration of how decisions can be layered.
We can also nest loops. A common scenario is iterating over a 2D structure, like a grid or a matrix. Think of a multiplication table, where for each row, you iterate through each column to calculate the product.
for row in range(1, 6):
for col in range(1, 6):
product = row * col
print(f"{row} * {col} = {product}")
print("---") # Separator for each rowHere, the inner for col in range(1, 6): loop completes all its iterations for each single iteration of the outer for row in range(1, 6): loop. This creates a structured way to process data in multiple dimensions.
It's also possible to nest loops within if statements, and if statements within loops. This can lead to very flexible logic. For instance, you might iterate through a list of users and, for each user, check if they have administrative privileges before allowing them to perform certain actions.
users = [
{"name": "Alice", "is_admin": True},
{"name": "Bob", "is_admin": False},
{"name": "Charlie", "is_admin": True}
]
for user in users:
print(f"Checking permissions for {user['name']}...")
if user["is_admin"]:
print(f"{user['name']} is an administrator. Access granted.")
else:
print(f"{user['name']} is not an administrator. Access denied.")The nesting of control flow statements can become complex. As you write more nested code, consider using clear variable names, adding comments, and breaking down complex logic into smaller, manageable functions to maintain readability and prevent errors.
graph TD
A[Start]
B{Is condition A true?}
C[Perform action A]
D{Is condition B true?}
E[Perform action B]
F[Perform action C]
G[End]
A --> B
B -- Yes --> C
C --> D
B -- No --> G
D -- Yes --> E
E --> G
D -- No --> F
F --> G
This flowchart illustrates a nested decision structure: if condition A is true, we then check condition B. If condition B is also true, action B is performed. If condition B is false, action C is performed. If condition A is false, we skip the inner checks and proceed to the end.
graph TD
A[Start Outer Loop]
B[Outer Loop Iteration]
C[Start Inner Loop]
D[Inner Loop Iteration]
E[Perform Action]
F[End Inner Loop]
G[End Outer Loop]
A --> B
B --> C
C --> D
D --> E
E --> C
C --> F
F --> B
B --> G
This flowchart represents nested loops. The outer loop progresses, and for each of its iterations, the inner loop completes all of its iterations, performing the 'Perform Action' for every combination before the outer loop moves to its next iteration.