Skip to main content

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:

  1. Create empty list
  2. Loop through original list
  3. Check condition
  4. 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:

  1. Initialize counter to 0
  2. Loop through list
  3. Check condition
  4. 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:

  1. Create empty list
  2. Loop through original
  3. Transform each item
  4. 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:

  1. Start with first item
  2. Compare each item
  3. 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">

  1. Create a new file called loop_patterns.py
  2. Filtering:
    • List: areas = [450.5, 380.2, 520.8, 410.3, 395.7]
    • Create new list with only areas >= 400
    • Print the filtered list
  3. Counting:
    • Same list
    • Count how many are: small (< 400), standard (400-600), large (> 600)
    • Print counts for each category
  4. Transforming:
    • List: areas_sqm = [450, 380, 520]
    • Convert to square feet (multiply by 10.764)
    • Store in new list
    • Print both lists
  5. Using enumerate:
    • List: rooms = ["Office 1", "Office 2", "Conference", "Break Room"]
    • Print numbered list starting from 1
  6. Using zip:
    • Names: ["Office 1", "Office 2", "Conference"]
    • Areas: [12.5, 15.3, 45.8]
    • Print each: "Name: Area"
  7. Finding max:
    • List: areas = [450.5, 380.2, 520.8, 410.3]
    • Find largest area manually (don't use max())
    • Print result
  8. Accumulating:
    • Same list
    • Calculate total area
    • Calculate average (total / count)
    • Print both
  9. 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
  10. 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

</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.

Updated on Mar 27, 2026