Chapter 3: Control Flow & Loops - Master Python's Decision Making and Iteration
Welcome to the comprehensive guide to Python control flow and loops! This chapter covers conditional statements, loops, and program flow control that allow you to create dynamic and interactive Python programs. Understanding control flow is essential for writing logic-driven applications.
Learning Objectives
By the end of this chapter, you will understand:
- Conditional statements (if, elif, else) and their usage
- Comparison operators and logical operators
- For loops and iteration over sequences
- While loops and conditional iteration
- Loop control statements (break, continue, pass)
- Nested loops and complex iteration patterns
- Exception handling with try-except blocks
- Best practices for control flow in Python
Conditional Statements (if, elif, else)
Basic if Statement
The if
statement allows you to execute code conditionally:
# Basic if statement
age = 18
if age >= 18:
print("You are an adult")
# if-else statement
age = 16
if age >= 18:
print("You are an adult")
else:
print("You are a minor")
# if-elif-else statement
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}")
Comparison Operators
# Comparison operators
a, b = 10, 5
print(a == b) # Equal: False
print(a != b) # Not equal: True
print(a > b) # Greater than: True
print(a < b) # Less than: False
print(a >= b) # Greater or equal: True
print(a <= b) # Less or equal: False
# String comparison
name1, name2 = "Alice", "Bob"
print(name1 < name2) # True (lexicographic order)
# Chained comparisons
x = 5
print(1 < x < 10) # True
print(1 < x and x < 10) # Same as above
Logical Operators
# Logical operators
age = 25
has_license = True
has_car = False
# AND operator
if age >= 18 and has_license:
print("Can drive")
# OR operator
if has_license or has_car:
print("Has transportation")
# NOT operator
if not has_car:
print("Needs to buy a car")
# Complex conditions
if (age >= 18 and has_license) or (age >= 21 and has_car):
print("Can travel independently")
Nested Conditions
# Nested if statements
weather = "sunny"
temperature = 25
if weather == "sunny":
if temperature > 30:
print("It's hot! Stay hydrated")
elif temperature > 20:
print("Perfect weather for outdoor activities")
else:
print("Nice weather, but might be cool")
elif weather == "rainy":
print("Don't forget your umbrella")
else:
print("Check the weather forecast")
For Loops
Basic For Loop
For loops iterate over sequences:
# Iterating over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# Iterating over a string
word = "Python"
for char in word:
print(char)
# Using range()
for i in range(5):
print(i) # 0, 1, 2, 3, 4
for i in range(1, 6):
print(i) # 1, 2, 3, 4, 5
for i in range(0, 10, 2):
print(i) # 0, 2, 4, 6, 8
For Loop with enumerate()
# Using enumerate() to get index and value
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# Starting enumeration from a different number
for index, fruit in enumerate(fruits, start=1):
print(f"{index}. {fruit}")
For Loop with zip()
# Using zip() to iterate over multiple sequences
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["New York", "London", "Tokyo"]
for name, age, city in zip(names, ages, cities):
print(f"{name} is {age} years old and lives in {city}")
Dictionary Iteration
# Iterating over dictionaries
person = {"name": "Alice", "age": 30, "city": "New York"}
# Iterate over keys
for key in person:
print(key)
# Iterate over values
for value in person.values():
print(value)
# Iterate over key-value pairs
for key, value in person.items():
print(f"{key}: {value}")
While Loops
Basic While Loop
While loops repeat as long as a condition is true:
# Basic while loop
count = 0
while count < 5:
print(f"Count: {count}")
count += 1
# User input loop
while True:
user_input = input("Enter a number (or 'quit' to exit): ")
if user_input.lower() == 'quit':
break
try:
number = int(user_input)
print(f"You entered: {number}")
except ValueError:
print("Please enter a valid number")
While Loop with Condition
# While loop with condition
password = ""
correct_password = "secret123"
while password != correct_password:
password = input("Enter password: ")
if password != correct_password:
print("Incorrect password. Try again.")
print("Access granted!")
Loop Control Statements
Break Statement
The break
statement exits the loop immediately:
# Using break in for loop
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for num in numbers:
if num == 5:
break
print(num) # Prints: 1, 2, 3, 4
# Using break in while loop
count = 0
while count < 10:
if count == 5:
break
print(count)
count += 1
Continue Statement
The continue
statement skips the rest of the loop iteration:
# Using continue in for loop
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for num in numbers:
if num % 2 == 0: # Skip even numbers
continue
print(num) # Prints: 1, 3, 5, 7, 9
# Using continue in while loop
count = 0
while count < 10:
count += 1
if count % 2 == 0: # Skip even numbers
continue
print(count) # Prints: 1, 3, 5, 7, 9
Pass Statement
The pass
statement is a null operation:
# Using pass as placeholder
for i in range(5):
if i == 2:
pass # Do nothing
else:
print(i)
# Using pass in function definition
def future_function():
pass # Function body to be implemented later
Nested Loops
Nested For Loops
# Nested for loops
for i in range(3):
for j in range(3):
print(f"({i}, {j})")
# Multiplication table
for i in range(1, 6):
for j in range(1, 6):
print(f"{i} x {j} = {i * j}")
print() # Empty line after each row
Nested While Loops
# Nested while loops
outer = 0
while outer < 3:
inner = 0
while inner < 3:
print(f"Outer: {outer}, Inner: {inner}")
inner += 1
outer += 1
Exception Handling
Basic Try-Except
# Basic exception handling
try:
number = int(input("Enter a number: "))
result = 10 / number
print(f"Result: {result}")
except ValueError:
print("Please enter a valid number")
except ZeroDivisionError:
print("Cannot divide by zero")
except Exception as e:
print(f"An error occurred: {e}")
Try-Except-Else-Finally
# Complete exception handling
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("File not found")
except PermissionError:
print("Permission denied")
else:
print("File read successfully")
print(content)
finally:
print("This always executes")
if 'file' in locals():
file.close()
Custom Exceptions
# Custom exception class
class CustomError(Exception):
def __init__(self, message):
self.message = message
super().__init__(self.message)
# Using custom exception
def validate_age(age):
if age < 0:
raise CustomError("Age cannot be negative")
if age > 150:
raise CustomError("Age cannot be greater than 150")
return True
try:
validate_age(-5)
except CustomError as e:
print(f"Validation error: {e.message}")
Advanced Control Flow Patterns
List Comprehensions with Conditions
# List comprehension with if condition
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = [x for x in numbers if x % 2 == 0]
print(even_numbers) # [2, 4, 6, 8, 10]
# List comprehension with if-else
squares = [x**2 if x % 2 == 0 else x**3 for x in numbers]
print(squares) # [1, 4, 27, 16, 125, 36, 343, 64, 729, 100]
Generator Expressions
# Generator expression (memory efficient)
numbers = [1, 2, 3, 4, 5]
squares_gen = (x**2 for x in numbers)
for square in squares_gen:
print(square)
Walrus Operator (Python 3.8+)
# Walrus operator in while loop
while (line := input("Enter text (or 'quit'): ")) != 'quit':
print(f"You entered: {line}")
# Walrus operator in if statement
if (n := len([1, 2, 3, 4, 5])) > 3:
print(f"List has {n} elements")
Practical Examples
Example 1: Number Guessing Game
import random
def number_guessing_game():
"""A number guessing game with multiple difficulty levels."""
print("Welcome to the Number Guessing Game!")
# Choose difficulty
print("Choose difficulty:")
print("1. Easy (1-10)")
print("2. Medium (1-50)")
print("3. Hard (1-100)")
while True:
try:
difficulty = int(input("Enter choice (1-3): "))
if difficulty in [1, 2, 3]:
break
else:
print("Please enter 1, 2, or 3")
except ValueError:
print("Please enter a valid number")
# Set range based on difficulty
ranges = {1: (1, 10), 2: (1, 50), 3: (1, 100)}
min_num, max_num = ranges[difficulty]
# Generate random number
secret_number = random.randint(min_num, max_num)
attempts = 0
max_attempts = 7 if difficulty == 1 else 10 if difficulty == 2 else 15
print(f"I'm thinking of a number between {min_num} and {max_num}")
print(f"You have {max_attempts} attempts")
while attempts < max_attempts:
try:
guess = int(input(f"Attempt {attempts + 1}: Enter your guess: "))
attempts += 1
if guess == secret_number:
print(f"Congratulations! You guessed it in {attempts} attempts!")
return
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")
except ValueError:
print("Please enter a valid number")
attempts -= 1 # Don't count invalid input as attempt
print(f"Game over! The number was {secret_number}")
# Run the game
if __name__ == "__main__":
number_guessing_game()
Example 2: Text Analyzer
def text_analyzer():
"""Analyze text input for various statistics."""
print("Text Analyzer")
print("Enter text (type 'END' on a new line to finish):")
lines = []
while True:
line = input()
if line.strip().upper() == 'END':
break
lines.append(line)
if not lines:
print("No text entered")
return
# Combine all lines
full_text = '\n'.join(lines)
# Basic statistics
total_chars = len(full_text)
total_words = len(full_text.split())
total_lines = len(lines)
# Character analysis
letters = sum(1 for c in full_text if c.isalpha())
digits = sum(1 for c in full_text if c.isdigit())
spaces = sum(1 for c in full_text if c.isspace())
punctuation = sum(1 for c in full_text if c in ".,!?;:")
# Word frequency
words = full_text.lower().split()
word_freq = {}
for word in words:
# Remove punctuation from words
clean_word = ''.join(c for c in word if c.isalpha())
if clean_word:
word_freq[clean_word] = word_freq.get(clean_word, 0) + 1
# Most common words
most_common = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)[:5]
# Display results
print("\n" + "="*50)
print("TEXT ANALYSIS RESULTS")
print("="*50)
print(f"Total characters: {total_chars}")
print(f"Total words: {total_words}")
print(f"Total lines: {total_lines}")
print(f"Letters: {letters}")
print(f"Digits: {digits}")
print(f"Spaces: {spaces}")
print(f"Punctuation marks: {punctuation}")
if total_words > 0:
print(f"Average words per line: {total_words / total_lines:.1f}")
print(f"Average characters per word: {total_chars / total_words:.1f}")
print("\nMost common words:")
for word, count in most_common:
print(f" {word}: {count}")
# Longest word
if words:
longest_word = max(words, key=len)
print(f"\nLongest word: {longest_word} ({len(longest_word)} characters)")
# Run the analyzer
if __name__ == "__main__":
text_analyzer()
Example 3: Menu-Driven Calculator
def calculator():
"""A menu-driven calculator with multiple operations."""
print("Welcome to the Calculator!")
while True:
print("\nCalculator Menu:")
print("1. Addition")
print("2. Subtraction")
print("3. Multiplication")
print("4. Division")
print("5. Power")
print("6. Square root")
print("7. Exit")
try:
choice = int(input("Enter your choice (1-7): "))
except ValueError:
print("Please enter a valid number")
continue
if choice == 7:
print("Thank you for using the calculator!")
break
if choice in [1, 2, 3, 4, 5]:
try:
num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))
except ValueError:
print("Please enter valid numbers")
continue
if choice == 1:
result = num1 + num2
print(f"{num1} + {num2} = {result}")
elif choice == 2:
result = num1 - num2
print(f"{num1} - {num2} = {result}")
elif choice == 3:
result = num1 * num2
print(f"{num1} × {num2} = {result}")
elif choice == 4:
if num2 == 0:
print("Error: Division by zero")
else:
result = num1 / num2
print(f"{num1} ÷ {num2} = {result}")
elif choice == 5:
result = num1 ** num2
print(f"{num1}^{num2} = {result}")
elif choice == 6:
try:
num = float(input("Enter number: "))
if num < 0:
print("Error: Cannot calculate square root of negative number")
else:
import math
result = math.sqrt(num)
print(f"√{num} = {result}")
except ValueError:
print("Please enter a valid number")
else:
print("Invalid choice. Please enter 1-7.")
# Run the calculator
if __name__ == "__main__":
calculator()
Best Practices for Control Flow
Code Organization
# Good: Clear and readable conditions
def is_valid_age(age):
return 0 <= age <= 150
# Good: Early returns to reduce nesting
def process_user(user):
if not user:
return None
if not user.is_active:
return None
if not user.has_permission:
return None
# Process the user
return user.process()
# Good: Use meaningful variable names
is_weekend = day in ['Saturday', 'Sunday']
has_valid_license = user.age >= 18 and user.license_status == 'valid'
Performance Considerations
# Good: Use appropriate loop types
# For known iterations, use for loops
for item in items:
process(item)
# For conditional iteration, use while loops
while condition:
do_something()
# Good: Use list comprehensions for simple transformations
squares = [x**2 for x in range(10)]
# Good: Use generator expressions for large datasets
large_squares = (x**2 for x in range(1000000))
Summary
In this chapter, we've covered:
- Conditional statements: if, elif, else with comparison and logical operators
- For loops: iteration over sequences with enumerate() and zip()
- While loops: conditional iteration and user input handling
- Loop control: break, continue, and pass statements
- Nested loops: complex iteration patterns
- Exception handling: try-except-else-finally blocks
- Advanced patterns: list comprehensions, generators, and walrus operator
Control flow is the backbone of programming logic. Mastering these concepts allows you to create dynamic, interactive, and robust Python applications that can handle various conditions and user inputs effectively.
Next Steps
Now that you understand control flow, you're ready to explore:
- Functions: Create reusable code blocks with parameters and return values
- Object-Oriented Programming: Build classes and objects
- Modules and Packages: Organize code into reusable components
- File Handling: Read from and write to files
- Advanced Topics: Explore decorators, context managers, and more
Ready to create reusable code? Continue with Chapter 4: Functions to master Python function programming!