← Home

045. For Loop

Iterate over a sequence to process each element

045. For Loop

RAM Manager: Scanning Process List

Aryan’s RAM manager gets a list of process records from the OS. He needs to scan them to calculate total RAM usage and find the biggest offender.

processes = [
    {"name": "chrome",  "pid": 812, "mem_mb": 544},
    {"name": "python3", "pid": 421, "mem_mb": 398},
    {"name": "slack",   "pid": 234, "mem_mb": 256},
]

Python’s for item in items: iterates directly over elements — no index arithmetic, no items[i], no off-by-one errors. His total_mem function is broken because it tries to add the whole list to total instead of looping.


💡 Fun fact: Python’s for loop is technically a “foreach” loop, not a C-style index counter. This design was inspired by languages like Modula-3 and ABC (Python’s direct predecessor). The shift from index-based to element-based iteration eliminates an entire category of off-by-one bugs that plague C and Java code — researchers have identified off-by-one errors as one of the top five most common bugs in production software.

⚠️ Watch out: The accumulation pattern has three required parts: initialize before the loop, update inside the loop, and use the result after the loop. Beginners frequently put the initialization inside the loop (resetting it every iteration) or the return inside the loop (returning after only the first item). Both produce wrong results with no error.

🤔 Think about it: Aryan uses for item in items: total += item["weight"] to sum weights. Python also has sum(item["weight"] for item in items) — a generator expression that does the same thing in one line. When would you prefer the explicit for loop over the one-liner, and when does the one-liner make the code clearer?

Learning objectives

  • Use for loops to iterate over lists
  • Accumulate values in a loop with a running total
  • Collect filtered results with a loop and append

Key concepts

  • for loop
  • iteration
  • accumulation

Try it

Concept detail

‘for variable in iterable:’ runs the body once per element.

Works with any iterable: for item in my_list: # list for char in “hello”: # string (iterates characters) for key in my_dict: # dict keys for k, v in my_dict.items(): # dict key-value pairs for i in range(10): # integers 0..9 for i, item in enumerate(my_list): # index + item

Accumulation pattern — always three parts: total = 0 # 1. initialize BEFORE loop for x in numbers: total += x # 2. update INSIDE loop return total # 3. return AFTER loop

The loop variable is accessible AFTER the loop ends (it holds the last value). For an empty list, the body never runs — the variable never gets set. This is why you initialize accumulators before the loop (handles the empty case).

Python’s for loop is a “foreach” — it iterates VALUES, not indices. Use enumerate() when you need both the index and the value: for i, item in enumerate(items): print(f“{i}: {item}“)

Solution

def total_weight(items):
    total = 0
    for item in items:
        total += item["weight"]
    return total

def find_heaviest(items):
    heaviest = items[0]
    for item in items:
        if item["weight"] > heaviest["weight"]:
            heaviest = item
    return heaviest

def names_over_weight(items, limit):
    result = []
    for item in items:
        if item["weight"] > limit:
            result.append(item["name"])
    return result

Tests

ITEMS = [
    {"name": "box", "weight": 10},
    {"name": "crate", "weight": 50},
    {"name": "bag", "weight": 5},
]

def test_total_weight():
    assert total_weight(ITEMS) == 65

def test_total_weight_no_typeerror():
    # broken code: total += items raises TypeError (can't add list to int)
    try:
        result = total_weight(ITEMS)
        assert isinstance(result, (int, float)), "total_weight must return a number"
    except TypeError:
        assert False, "TypeError: missing for loop — total += items tries to add a list to an int"

def test_find_heaviest():
    assert find_heaviest(ITEMS)["name"] == "crate"

def test_names_over_weight():
    result = names_over_weight(ITEMS, 8)
    assert "box" in result
    assert "crate" in result
    assert "bag" not in result

def test_empty_list():
    assert total_weight([]) == 0

def test_single_item():
    assert total_weight([{"name": "x", "weight": 42}]) == 42

Resources