Built with Tutify.io

    AIStudyLabs

    Common Loop Patterns and Idioms

    Common Loop Patterns and Idioms

    Introduction

    In this lesson, you will move beyond basic for and while syntax and learn how to structure loops to solve common real-world problems. We’ll focus on reusable loop patterns and idioms that appear in almost every Python program:

    You already know how loops work mechanically; now you’ll learn to recognize and apply patterns that make your code clearer and more efficient.


    Choosing Between for, while, and Nested Loops

    When to Use for

    Use a for loop when:

    Example: process each item in a shopping cart exactly once.

    cart = [10.99, 4.50, 2.75]
    
    for price in cart:
        tax = price * 0.1
        print(f"Price: {price}, Tax: {tax}")
    
    # Output
    Price: 10.99, Tax: 1.099
    Price: 4.5, Tax: 0.45
    Price: 2.75, Tax: 0.275
    

    Here the number of iterations is determined by the number of items in cart, so for is the natural choice.

    When to Use while

    Use a while loop when the number of repetitions is not known in advance and depends on a changing condition.

    Example: keep asking for input until the user types quit.

    command = ""
    
    while command != "quit":
        command = input("Enter a command (or 'quit' to exit): ")
        print(f"You entered: {command}")
    
    # Output (example interaction)
    Enter a command (or 'quit' to exit): run
    You entered: run
    Enter a command (or 'quit' to exit): status
    You entered: status
    Enter a command (or 'quit' to exit): quit
    You entered: quit
    

    The loop continues based on the state (command), not on a fixed count.

    When to Use Nested Loops

    Use nested loops when you need to combine or compare every element of one sequence with every element of another, or iterate through multi-dimensional data.

    Example: generate all (row, column) positions in a grid.

    rows = 3
    cols = 2
    
    for r in range(rows):
        for c in range(cols):
            print(f"Cell: ({r}, {c})")
    
    # Output
    Cell: (0, 0)
    Cell: (0, 1)
    Cell: (1, 0)
    Cell: (1, 1)
    Cell: (2, 0)
    Cell: (2, 1)
    

    Each inner-loop iteration pairs a column with the current row from the outer loop.


    Counter-Controlled Loops and Fixed Repetition

    A counter-controlled loop uses a variable (counter) to run the loop a fixed number of times.

    Fixed Repetition Task

    times = int(input("How many stars should I print? "))
    
    for i in range(times):
        print("*", end="")
    print()  # newline
    
    # Output (if user enters 5)
    How many stars should I print? 5
    *****
    

    range(times) creates exactly times iterations; i acts as a counter even though we don’t use its value directly.

    Aggregation with a Counter

    Counter-controlled loops often appear in aggregations, like computing the total of several inputs.

    n = int(input("How many numbers? "))
    
    total = 0
    for i in range(n):
        value = float(input(f"Enter number {i + 1}: "))
        total += value
    
    print("Total:", total)
    
    # Output (example)
    How many numbers? 3
    Enter number 1: 2.5
    Enter number 2: 1.5
    Enter number 3: 6
    Total: 10.0
    

    The counter i ensures we ask for exactly n numbers and accumulate them into total.


    Loop Patterns for Searching, Filtering, and Selecting

    Linear Search Pattern

    The search pattern walks through a sequence looking for the first element that matches a condition.

    numbers = [3, 10, 7, 21, 5]
    target = 21
    
    found_index = None
    
    for i, num in enumerate(numbers):
        if num == target:
            found_index = i
            break
    
    if found_index is not None:
        print(f"Found {target} at index {found_index}")
    else:
        print(f"{target} not found")
    
    # Output
    Found 21 at index 3
    

    We maintain found_index as the result of the search and use break to stop as soon as we’ve found the target.

    Filtering Pattern

    The filtering pattern builds a new collection containing only items that satisfy a condition.

    scores = [95, 62, 88, 47, 73, 100]
    
    passing_scores = []
    for score in scores:
        if score >= 70:
            passing_scores.append(score)
    
    print("Passing:", passing_scores)
    
    # Output
    Passing: [95, 88, 73, 100]
    

    Instead of modifying the original list, we create a new list and selectively append items.

    Selecting Best (or Worst) Item

    The selection pattern finds an item with the minimum/maximum value based on some criterion.

    prices = [19.99, 5.49, 12.30, 3.99]
    
    cheapest_price = prices[0]
    
    for price in prices[1:]:
        if price < cheapest_price:
            cheapest_price = price
    
    print("Cheapest price:", cheapest_price)
    
    # Output
    Cheapest price: 3.99
    

    We start with the first element as the current best and update it whenever we find a better candidate.


    Accumulator and Running Total Idioms

    An accumulator variable keeps a running result across loop iterations (sum, count, product, etc.).

    Sum and Count for Average

    numbers = [4, 8, 15, 16, 23, 42]
    
    count = 0
    sum_values = 0
    
    for num in numbers:
        sum_values += num
        count += 1
    
    average = sum_values / count if count > 0 else 0
    
    print("Sum:", sum_values)
    print("Count:", count)
    print("Average:", average)
    
    # Output
    Sum: 108
    Count: 6
    Average: 18.0
    

    Here, sum_values and count are accumulators updated each iteration. This idiom generalizes to any metric you want to collect.

    Multiple Accumulators

    You can maintain several running totals at once.

    transactions = [100, -20, 50, -10, -5]
    
    deposits = 0
    withdrawals = 0
    
    for amount in transactions:
        if amount > 0:
            deposits += amount
        else:
            withdrawals += -amount  # store withdrawals as positive totals
    
    print("Total deposits:", deposits)
    print("Total withdrawals:", withdrawals)
    
    # Output
    Total deposits: 150
    Total withdrawals: 35
    

    Different accumulators track different aspects of the same data.


    Controlling Complex Loop Flows: break, continue, and Flags

    You’ve already seen simple break and continue usage. Now we’ll combine them with flags to manage more complex logic.

    Using Flags to Track Conditions Across Iterations

    A flag variable is a boolean that remembers whether something has happened during the loop.

    Example: check if any number is negative.

    values = [5, 3, 0, -1, 7]
    
    has_negative = False
    
    for v in values:
        if v < 0:
            has_negative = True
            break
    
    if has_negative:
        print("There is at least one negative value.")
    else:
        print("All values are non-negative.")
    
    # Output
    There is at least one negative value.
    

    The flag has_negative summarizes the result of the loop.

    Combining continue with Flags

    Sometimes you want to skip some iterations but still keep overall state.

    lines = [
        "# Comment line",
        "   ",
        "value1=10",
        "value2=20",
    ]
    
    non_empty_lines = 0
    
    for line in lines:
        stripped = line.strip()
    
        if stripped == "":
            continue          # skip blank lines
        if stripped.startswith("#"):
            continue          # skip comments
    
        non_empty_lines += 1
    
    print("Number of meaningful lines:", non_empty_lines)
    
    # Output
    Number of meaningful lines: 2
    

    continue jumps to the next iteration for lines we don’t care about, while non_empty_lines accumulates useful ones.

    Nested Loops with break and Flags

    In nested loops, break only exits the inner loop. Flags help when you need to influence the outer loop based on inner-loop results.

    matrix = [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
    ]
    
    target = 5
    found = False
    
    for r, row in enumerate(matrix):
        for c, value in enumerate(row):
            if value == target:
                print(f"Found {target} at ({r}, {c})")
                found = True
                break  # exits inner loop
        if found:
            break      # exits outer loop
    
    if not found:
        print("Target not found")
    
    # Output
    Found 5 at (1, 1)
    

    The found flag allows the outer loop to know that the inner loop has already located the target and can stop.


    Summary / Key Takeaways

    In this lesson on Common Loop Patterns and Idioms, you have learned:

    Python Programming – Complete Course with Practical Examples — Loops and Iteration Patterns

    Getting Started with Python and the Course

    Python Syntax, Indentation, and Core Concepts

    Variables, Data Types, and Type Conversion

    Operators, Expressions, and Control Flow

    Loops and Iteration Patterns

    Working with Strings in Depth

    Collections: Lists, Tuples, Sets, and Dictionaries

    Functions and Program Structuring

    Functional Programming Concepts in Python

    Modules, Packages, and Code Organization

    Error Handling and Debugging Fundamentals

    File Handling and Data Formats

    Object-Oriented Programming in Python

    Advanced Python: Iterators, Generators, and Decorators

    Python Standard Library for Real-World Tasks

    Python for Automation and Scripting

    Testing and Quality Assurance in Python

    Tutorial Not Found