Practical Software Development Fundamentals
Advanced Control Flow
Combining Logic and Loops
You already know how to make decisions with if and repeat tasks with for and while. The real power comes when you start combining them. Nested structures—placing a loop inside another loop, or an if statement inside a loop—allow you to handle more complex, multi-layered problems.
Imagine you have a list of students, and each student has a list of scores. To find the average score for each student, you need to loop through the students and then, for each one, loop through their scores. This is a classic case for a nested loop.
students = {
"Alice": [88, 92, 100],
"Bob": [75, 81, 89],
"Charlie": [90, 85, 95]
}
# Outer loop iterates through students
for student, scores in students.items():
total_score = 0
# Inner loop iterates through scores for one student
for score in scores:
total_score += score
average = total_score / len(scores)
print(f"{student}'s average score: {average:.2f}")
Controlling the Flow
Sometimes, you don't want a loop to run its full course. Python gives you tools to manage a loop's execution from within. The break, continue, and pass statements let you alter the standard flow.
break: Exits the innermost loop immediately. continue: Skips the rest of the current iteration and moves to the next one. pass: Does nothing. It's a placeholder for when syntax requires a statement, but you don't need any code to execute.
Let's say we want to find the first student who scored a perfect 100. We can use break to stop searching once we've found them.
for student, scores in students.items():
print(f"Checking {student}'s scores...")
for score in scores:
if score < 80:
# Skip this low score and check the next one
continue
if score == 100:
print(f"Found a perfect score for {student}!")
# We found what we wanted, so exit the inner loop
break
else:
# This 'else' belongs to the for loop.
# It runs only if the loop completed without a 'break'.
print(f"{student} has no perfect scores.")
continue # Move to the next student
# This code runs only if the inner loop was broken
break # Exit the outer loop as well
Pythonic Control Flow
As you get more comfortable with Python, you'll discover more elegant ways to write your logic. Writing code means leveraging the language's features to create solutions that are both concise and highly readable. Comprehensions are a prime example.
A list comprehension creates a new list by applying an expression to each item in an iterable. It's like a for loop, an append call, and an optional if condition all packed into one readable line.
# The standard way
numbers = [1, 2, 3, 4, 5, 6]
squares_of_evens = []
for num in numbers:
if num % 2 == 0:
squares_of_evens.append(num * num)
# The Pythonic way with a list comprehension
squares_of_evens_comp = [num * num for num in numbers if num % 2 == 0]
print(squares_of_evens) # Output: [4, 16, 36]
print(squares_of_evens_comp) # Output: [4, 16, 36]
Similarly, dictionary comprehensions let you build dictionaries concisely. You can create a new dictionary from any iterable of key-value pairs or transform an existing dictionary.
# Create a dictionary of numbers and their squares
# The comprehension way is much shorter!
square_map = {x: x*x for x in range(1, 6)}
print(square_map)
# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Another tool for concise code is the ternary operator, which is a one-line if-else statement. It's useful for simple conditional assignments.
# Standard if-else
age = 20
if age >= 18:
status = "Adult"
else:
status = "Minor"
# Ternary operator version
status_ternary = "Adult" if age >= 18 else "Minor"
print(status) # Output: Adult
print(status_ternary) # Output: Adult
Efficient Logic
Understanding how Python evaluates logical expressions can help you write more efficient and bug-free code. The and and or operators use a technique called evaluation.
For
a and b, ifaisFalse, Python doesn't evaluatebat all. Fora or b, ifaisTrue, Python doesn't evaluatebat all.
This is useful when the second part of a condition might cause an error if the first part isn't true. For example, checking if a list has elements before trying to access one.
my_list = []
# This would cause an IndexError: my_list[0]
# if my_list[0] == 'hello' and len(my_list) > 0:
# print("Found it!")
# Short-circuiting prevents the error.
# Because len(my_list) > 0 is False, the second part is never checked.
if len(my_list) > 0 and my_list[0] == 'hello':
print("Found it!")
else:
print("List is empty or doesn't start with 'hello'.")
# Output: List is empty or doesn't start with 'hello'.
These advanced control flow techniques are the building blocks for creating sophisticated, efficient, and readable Python programs. Mastering them moves you from simply writing code that works to writing code that is truly elegant. With these tools, you can handle complex logic with grace.
What is a primary use case for nested loops in programming?
What will be printed by the following Python code?
for i in range(1, 6):
if i == 3:
break
print(i, end=' ')