Lesson 19: Common Loop Patterns
Learn Python basics like filtering lists, counting with conditions, transforming data, using enumerate and zip, and finding min/max with simple logic.
Introduction
You know how to write for loops. You know how to control them with break and continue.
Now you need to know the patterns — the common ways loops are actually used in real code.
Filtering lists. Counting items that meet criteria. Transforming data. Getting both index and item. Processing pairs of values.
These patterns come up repeatedly. Learn them once, use them everywhere.
Lesson Overview
This section contains a general overview of topics you will learn in this lesson.
- Filtering (building new lists based on conditions)
- Counting with conditions
- Transforming data
- Using enumerate() for index and item
- Using zip() to process pairs
- Finding min/max manually
- Accumulating values
Pattern 1: Filtering
Build a new list containing only items that meet a condition.
room_areas = [450.5, 380.2, 520.8, 410.3, 395.7]
# Get only large rooms (>= 500)
large_rooms = []
for area in room_areas:
if area >= 500:
large_rooms.append(area)
print(large_rooms)
# Output: [520.8]
The pattern:
- Create empty list
- Loop through original list
- Check condition
- Append matching items
Architectural Example: Filter by Discipline
sheets = ["A-101", "A-102", "S-101", "A-201", "M-101", "S-102"]
# Get only architectural sheets
arch_sheets = []
for sheet in sheets:
if sheet.startswith("A"):
arch_sheets.append(sheet)
print(f"Architectural sheets: {arch_sheets}")
# Output: Architectural sheets: ['A-101', 'A-102', 'A-201']
Pattern 2: Counting with Conditions
Count how many items meet specific criteria.
room_areas = [450.5, 380.2, 520.8, 410.3, 395.7]
# Count compliant rooms
compliant_count = 0
for area in room_areas:
if area >= 400:
compliant_count += 1
print(f"Compliant rooms: {compliant_count} out of {len(room_areas)}")
# Output: Compliant rooms: 3 out of 5
The pattern:
- Initialize counter to 0
- Loop through list
- Check condition
- Increment counter if true
Architectural Example: Count by Status
sheets = ["A-101", "A-102", "A-201", "A-202", "S-101"]
issued = ["A-101", "A-201", "S-101"]
issued_count = 0
draft_count = 0
for sheet in sheets:
if sheet in issued:
issued_count += 1
else:
draft_count += 1
print(f"Issued: {issued_count}")
print(f"Draft: {draft_count}")
# Output:
# Issued: 3
# Draft: 2
Pattern 3: Transforming Data
Create a new list by transforming each item.
areas_sqm = [450.5, 380.2, 520.8]
# Convert to square feet
areas_sqft = []
for area in areas_sqm:
area_sqft = area * 10.764
areas_sqft.append(area_sqft)
print(areas_sqft)
# Output: [4849.122, 4092.4528, 5605.8752]
The pattern:
- Create empty list
- Loop through original
- Transform each item
- Append transformed value
Architectural Example: Generate File Names
sheet_numbers = ["A-101", "A-102", "A-201"]
project_code = "2024-001"
file_names = []
for sheet in sheet_numbers:
file_name = f"{project_code}_{sheet}_Plan.pdf"
file_names.append(file_name)
for name in file_names:
print(name)
# Output:
# 2024-001_A-101_Plan.pdf
# 2024-001_A-102_Plan.pdf
# 2024-001_A-201_Plan.pdf
Pattern 4: Using enumerate()
Get both the index and the item in each iteration.
rooms = ["Office 1", "Office 2", "Conference"]
for index, room in enumerate(rooms):
print(f"Room {index}: {room}")
# Output:
# Room 0: Office 1
# Room 1: Office 2
# Room 2: Conference
Start counting from 1:
for index, room in enumerate(rooms, start=1):
print(f"Room {index}: {room}")
# Output:
# Room 1: Office 1
# Room 2: Office 2
# Room 3: Conference
Why enumerate() Is Useful
Without enumerate (awkward):
rooms = ["Office 1", "Office 2", "Conference"]
for i in range(len(rooms)):
print(f"Room {i+1}: {rooms[i]}")
With enumerate (cleaner):
for i, room in enumerate(rooms, start=1):
print(f"Room {i}: {room}")
Architectural Example: Numbered Room List
rooms = ["Office 1", "Office 2", "Conference", "Break Room"]
print("Room Schedule:")
print("-" * 40)
for number, room in enumerate(rooms, start=1):
print(f"{number}. {room}")
# Output:
# Room Schedule:
# ----------------------------------------
# 1. Office 1
# 2. Office 2
# 3. Conference
# 4. Break Room
Pattern 5: Using zip()
Process two lists together, pairing up items at the same index.
room_names = ["Office 1", "Office 2", "Conference"]
room_areas = [12.5, 15.3, 45.8]
for name, area in zip(room_names, room_areas):
print(f"{name}: {area}m²")
# Output:
# Office 1: 12.5m²
# Office 2: 15.3m²
# Conference: 45.8m²
zip() pairs up items: first with first, second with second, etc.
How zip() Works
names = ["A", "B", "C"]
numbers = [1, 2, 3]
for name, number in zip(names, numbers):
print(f"{name} - {number}")
# Output:
# A - 1
# B - 2
# C - 3
If lists have different lengths, zip() stops at the shortest:
names = ["A", "B", "C"]
numbers = [1, 2]
for name, number in zip(names, numbers):
print(f"{name} - {number}")
# Output:
# A - 1
# B - 2
# (C is not processed)
Architectural Example: Room Report
room_names = ["Office 1", "Office 2", "Conference", "Break Room"]
room_areas = [12.5, 15.3, 45.8, 18.2]
room_types = ["Private", "Private", "Meeting", "Common"]
print("Room Schedule:")
print("-" * 60)
for name, area, room_type in zip(room_names, room_areas, room_types):
print(f"{name:15} {area:6.1f}m² ({room_type})")
# Output:
# Room Schedule:
# ------------------------------------------------------------
# Office 1 12.5m² (Private)
# Office 2 15.3m² (Private)
# Conference 45.8m² (Meeting)
# Break Room 18.2m² (Common)
Pattern 6: Finding Min/Max Manually
Sometimes you need to find the smallest or largest item while tracking additional info.
room_areas = [450.5, 380.2, 520.8, 410.3]
smallest = room_areas[0]
for area in room_areas:
if area < smallest:
smallest = area
print(f"Smallest room: {smallest}m²")
# Output: Smallest room: 380.2m²
The pattern:
- Start with first item
- Compare each item
- Update if condition is met
Architectural Example: Find Largest Non-Compliant Room
room_data = [
{"name": "Office 1", "area": 420},
{"name": "Office 2", "area": 380},
{"name": "Office 3", "area": 395},
{"name": "Office 4", "area": 450},
]
minimum_area = 400
largest_non_compliant = None
for room in room_data:
if room["area"] < minimum_area:
if largest_non_compliant is None or room["area"] > largest_non_compliant["area"]:
largest_non_compliant = room
if largest_non_compliant:
print(f"Largest non-compliant: {largest_non_compliant['name']} ({largest_non_compliant['area']}m²)")
else:
print("All rooms compliant")
# Output: Largest non-compliant: Office 3 (395m²)
Pattern 7: Accumulating Values
Build up a total by adding each item.
room_areas = [450.5, 380.2, 520.8, 410.3]
total_area = 0
for area in room_areas:
total_area += area
print(f"Total area: {total_area}m²")
# Output: Total area: 1761.8m²
You can also accumulate other things:
# Build a string
sheet_list = ["A-101", "A-102", "A-201"]
result = ""
for sheet in sheet_list:
result += sheet + ", "
result = result.rstrip(", ") # Remove trailing comma
print(result)
# Output: A-101, A-102, A-201
Combining Patterns
Real code often combines multiple patterns.
Filter and count:
room_areas = [450.5, 380.2, 520.8, 410.3, 395.7]
large_rooms = []
compliant_count = 0
for area in room_areas:
# Filter
if area >= 500:
large_rooms.append(area)
# Count
if area >= 400:
compliant_count += 1
print(f"Large rooms: {large_rooms}")
print(f"Compliant: {compliant_count}")
# Output:
# Large rooms: [520.8]
# Compliant: 3
Real Architectural Workflows
Example 1: Comprehensive Room Analysis
room_names = ["Office 1", "Office 2", "Conference", "Office 3", "Break Room"]
room_areas = [12.5, 15.3, 45.8, 11.2, 18.2]
# Multiple analyses in one loop
total_area = 0
office_count = 0
small_rooms = []
for name, area in zip(room_names, room_areas):
# Accumulate total
total_area += area
# Count offices
if "Office" in name:
office_count += 1
# Filter small rooms
if area < 15:
small_rooms.append(name)
print(f"Total area: {total_area}m²")
print(f"Offices: {office_count}")
print(f"Small rooms: {small_rooms}")
# Output:
# Total area: 103.0m²
# Offices: 3
# Small rooms: ['Office 1', 'Office 3']
Example 2: Sheet Processing Report
sheets = ["A-101", "A-102", "A-201", "S-101", "S-102"]
issued = ["A-101", "S-101"]
print("Sheet Processing Report:")
print("-" * 50)
processed = []
skipped = []
for i, sheet in enumerate(sheets, start=1):
if sheet in issued:
status = "Issued - Skipped"
skipped.append(sheet)
else:
status = "Draft - Processed"
processed.append(sheet)
print(f"{i}. {sheet}: {status}")
print()
print(f"Processed: {len(processed)} sheets")
print(f"Skipped: {len(skipped)} sheets")
# Output:
# Sheet Processing Report:
# --------------------------------------------------
# 1. A-101: Issued - Skipped
# 2. A-102: Draft - Processed
# 3. A-201: Draft - Processed
# 4. S-101: Issued - Skipped
# 5. S-102: Draft - Processed
#
# Processed: 3 sheets
# Skipped: 2 sheets
Example 3: Building Code Compliance Check
rooms = ["Office 1", "Office 2", "Storage", "Office 3"]
areas = [12.5, 15.3, 8.2, 11.8]
heights = [2.8, 2.9, 2.5, 2.7]
minimum_area = 12.0
minimum_height = 2.7
compliant = []
violations = []
for name, area, height in zip(rooms, areas, heights):
issues = []
if area < minimum_area:
issues.append(f"area {area}m² < {minimum_area}m²")
if height < minimum_height:
issues.append(f"height {height}m < {minimum_height}m")
if issues:
violations.append(f"{name}: {', '.join(issues)}")
else:
compliant.append(name)
print("Compliance Report:")
print("-" * 50)
print(f"Compliant: {len(compliant)}")
for room in compliant:
print(f" ✓ {room}")
print(f"\\nViolations: {len(violations)}")
for violation in violations:
print(f" ✗ {violation}")
# Output:
# Compliance Report:
# --------------------------------------------------
# Compliant: 2
# ✓ Office 1
# ✓ Office 2
#
# Violations: 2
# ✗ Storage: area 8.2m² < 12.0m², height 2.5m < 2.7m
# ✗ Office 3: height 2.7m < 2.7m
When to Use Each Pattern
Filtering: Need only items that meet criteria Counting: Need totals for different categories Transforming: Need modified version of each item enumerate(): Need position and item together zip(): Need to process multiple lists together Finding min/max: Need extremes with additional context Accumulating: Need running totals or combined values
Assignment
<div class="lesson-content__panel" markdown="1">
- Create a new file called
loop_patterns.py - Filtering:
- List:
areas = [450.5, 380.2, 520.8, 410.3, 395.7] - Create new list with only areas >= 400
- Print the filtered list
- List:
- Counting:
- Same list
- Count how many are: small (< 400), standard (400-600), large (> 600)
- Print counts for each category
- Transforming:
- List:
areas_sqm = [450, 380, 520] - Convert to square feet (multiply by 10.764)
- Store in new list
- Print both lists
- List:
- Using enumerate:
- List:
rooms = ["Office 1", "Office 2", "Conference", "Break Room"] - Print numbered list starting from 1
- List:
- Using zip:
- Names:
["Office 1", "Office 2", "Conference"] - Areas:
[12.5, 15.3, 45.8] - Print each: "Name: Area"
- Names:
- Finding max:
- List:
areas = [450.5, 380.2, 520.8, 410.3] - Find largest area manually (don't use max())
- Print result
- List:
- Accumulating:
- Same list
- Calculate total area
- Calculate average (total / count)
- Print both
- Combining patterns:
- Names:
["Office 1", "Office 2", "Office 3", "Storage"] - Areas:
[12.5, 15.3, 11.2, 8.5] - Use zip to process both
- Filter offices only (name contains "Office")
- Calculate total office area
- Count offices
- Print summary
- Names:
- Real scenario - Compliance analysis:
- Rooms:
["Office 1", "Office 2", "Storage", "Office 3"] - Areas:
[12.5, 15.3, 8.2, 11.8] - Minimum: 12.0
- Use enumerate and zip
- Create compliant list and non-compliant list
- Print numbered report showing each room's status
- Rooms:
</div>
Knowledge Check
The following questions are an opportunity to reflect on key topics in this lesson.
- <a class="knowledge-check-link" href="#pattern-1-filtering">How do you build a filtered list?</a>
- <a class="knowledge-check-link" href="#pattern-2-counting-with-conditions">How do you count items that meet a condition?</a>
- <a class="knowledge-check-link" href="#pattern-3-transforming-data">How do you create a transformed version of a list?</a>
- <a class="knowledge-check-link" href="#pattern-4-using-enumerate">What does enumerate() give you?</a>
- <a class="knowledge-check-link" href="#pattern-5-using-zip">What does zip() do with two lists?</a>
- <a class="knowledge-check-link" href="#pattern-7-accumulating-values">How do you calculate a running total?</a>
Additional Resources
This section contains helpful links to related content. It isn't required, so consider it supplemental.
- Python's enumerate() documentation covers additional parameters and use cases
- Python's zip() documentation explains how to handle unequal length lists
- Real Python's guide to Python enumerate() provides comprehensive examples