Control Flow
Break and Continue
Loop Control
You're scanning a list of 10,000 products for item #4521. Once found, why keep
searching? break lets you exit immediately. Or you're processing orders but
want to skip cancelled ones - continue jumps to the next iteration.
Find first match (break)
Stop searching once you find what you're looking for.
numbers = [10, 25, 30, 42, 55, 60]
target =
found_index = -1
for i, num in enumerate(numbers):
print(f"Checking index {i}: {num}")
if num == target:
found_index = i
break
if found_index != -1:
print(f"Found {target} at index {found_index}")
else:
print(f"{target} not found")
# Without break, would check all elements unnecessarily
# With break, stops at first match
numbers = [10, 25, 30, 42, 55, 60]
target =
found_index = -1
for i, num in enumerate(numbers):
print(f"Checking index {i}: {num}")
if num == target:
found_index = i
break
if found_index != -1:
print(f"Found {target} at index {found_index}")
else:
print(f"{target} not found")
# Without break, would check all elements unnecessarily
# With break, stops at first match
numbers = [10, 25, 30, 42, 55, 60]
target =
found_index = -1
for i, num in enumerate(numbers):
print(f"Checking index {i}: {num}")
if num == target:
found_index = i
break
if found_index != -1:
print(f"Found {target} at index {found_index}")
else:
print(f"{target} not found")
# Without break, would check all elements unnecessarily
# With break, stops at first match
break exits the loop immediately. More efficient than checking all elements.
Skip invalid entries (continue)
Skip items that don't meet criteria without stopping the loop.
scores = [85, -1, 92, 0, 78, -5, 95] # -1 and -5 are invalid
total = 0
count = 0
print("Processing scores:")
for score in scores:
if score < 0:
print(f" Skipping invalid: {score}")
continue
print(f" Adding: {score}")
total += score
count += 1
print(f"Valid scores: {count}")
print(f"Sum: {total}")
if count > 0:
print(f"Average: {total // count}")
# Pythonic alternative: filter
valid_scores = [s for s in scores if s >= 0]
print(f"\nFiltered: {valid_scores}")
print(f"Average: {sum(valid_scores) // len(valid_scores)}")
continue jumps to the next iteration, skipping the rest of the loop body.
Early exit on error
Stop processing if something goes wrong.
commands =
success = True
for cmd in commands:
print(f"Executing: {cmd}")
# Stop on error
if cmd == "error":
print("ERROR: Operation failed!")
success = False
break
print(" Done.")
if success:
print("All commands completed successfully.")
else:
print("Processing stopped due to error.")
commands =
success = True
for cmd in commands:
print(f"Executing: {cmd}")
# Stop on error
if cmd == "error":
print("ERROR: Operation failed!")
success = False
break
print(" Done.")
if success:
print("All commands completed successfully.")
else:
print("Processing stopped due to error.")
commands =
success = True
for cmd in commands:
print(f"Executing: {cmd}")
# Stop on error
if cmd == "error":
print("ERROR: Operation failed!")
success = False
break
print(" Done.")
if success:
print("All commands completed successfully.")
else:
print("Processing stopped due to error.")
Validate early and break if invalid - cleaner than deep nesting.
Process until sentinel
Process data until you encounter a special "stop" value.
# Data with sentinel value -1 marking end
data =
print("Processing until sentinel (-1):")
total = 0
for value in data:
if value == -1:
print("Sentinel found, stopping.")
break
print(f"Processing: {value}")
total += value
print(f"Sum of processed values: {total}")
# Pythonic: itertools.takewhile
from itertools import takewhile
print("\nUsing takewhile:")
data2 = [10, 20, 30, 40, -1, 50, 60]
for value in takewhile(lambda x: x != -1, data2):
print(f"Processing: {value}")
total2 = sum(takewhile(lambda x: x != -1, data2))
print(f"Sum: {total2}")
# Data with sentinel value -1 marking end
data =
print("Processing until sentinel (-1):")
total = 0
for value in data:
if value == -1:
print("Sentinel found, stopping.")
break
print(f"Processing: {value}")
total += value
print(f"Sum of processed values: {total}")
# Pythonic: itertools.takewhile
from itertools import takewhile
print("\nUsing takewhile:")
data2 = [10, 20, 30, 40, -1, 50, 60]
for value in takewhile(lambda x: x != -1, data2):
print(f"Processing: {value}")
total2 = sum(takewhile(lambda x: x != -1, data2))
print(f"Sum: {total2}")
# Data with sentinel value -1 marking end
data =
print("Processing until sentinel (-1):")
total = 0
for value in data:
if value == -1:
print("Sentinel found, stopping.")
break
print(f"Processing: {value}")
total += value
print(f"Sum of processed values: {total}")
# Pythonic: itertools.takewhile
from itertools import takewhile
print("\nUsing takewhile:")
data2 = [10, 20, 30, 40, -1, 50, 60]
for value in takewhile(lambda x: x != -1, data2):
print(f"Processing: {value}")
total2 = sum(takewhile(lambda x: x != -1, data2))
print(f"Sum: {total2}")
Sentinel values signal "end of data" - common in file and stream processing.
For-else (Python unique!)
Python's for-else executes else only if loop completes without break.
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
# Python's unique for-else construct
numbers = [10, 25, 30, 42, 55, 60]
target =
# for-else: else runs only if loop completes WITHOUT break
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
break
else:
print(f"{target} not found")
# Equivalent without for-else
print("\n--- Without for-else ---")
found = False
for i, num in enumerate(numbers):
if num == target:
print(f"Found {target} at index {i}")
found = True
break
if not found:
print(f"{target} not found")
# Practical: search with validation
print("\n--- Practical example ---")
users = [
{"id": 1, "name": "Alice", "active": True},
{"id": 2, "name": "Bob", "active": False},
{"id": 3, "name": "Charlie", "active": True},
]
search_id =
for user in users:
if user["id"] == search_id:
print(f"Found user: {user['name']}")
break
else:
print(f"User {search_id} not found")
for-else is a Pythonic way to handle "not found" scenarios.
Exercise: refactoring.py
Explore Pythonic alternatives to break/continue