Walk lists inside records
An order holds a list of line items; a push event holds a list of commits. A loop inside a loop visits every inner item, with the outer record still at hand.
- Write an outer loop over records and an inner loop over the list each record holds
- Use fields of the outer record while visiting the inner items
- Put an accumulator before the outer loop so it collects across every record
An order isn't one product: it's a record with its own fields and a list of line items. To answer *how many units of each product did we sell?* you must visit every line of every order.
That is a loop inside a loop. The outer loop takes one record at a time; the inner loop walks the list stored in that record. Inside the inner loop, both the line item and its order are available.
Run each example to see what it prints. Running examples doesn't count toward progress.
orders = [
{"order_id": "O100282", "items": [{"sku": "P0164", "qty": 2}, {"sku": "P0594", "qty": 1}]},
{"order_id": "O100918", "items": [{"sku": "P0209", "qty": 3}]},
]
for order in orders:
print(order["order_id"])
for item in order["items"]:
print(f" {item['sku']} x {item['qty']} (order {order['order_id']})")A classic slip is looping over the record instead of its list. A for over a dictionary visits its keys, which are text, so the next lookup fails.
order = {"order_id": "O100282", "items": [{"sku": "P0164", "qty": 2}]}
for item in order:
print(item)
print(item["sku"])To collect across all records, the accumulator goes before the outer loop. Then each inner pass adds to the same dictionary, and the result covers every order.
def units_per_sku(orders): units = {} for order in orders: for item in order["items"]: sku = item["sku"] if sku not in units: units[sku] = 0 units[sku] += item["qty"] return units orders = [ {"order_id": "O100282", "items": [{"sku": "P0164", "qty": 2}, {"sku": "P0594", "qty": 1}]}, {"order_id": "O100918", "items": [{"sku": "P0164", "qty": 3}]}, {"order_id": "O101219", "items": []}, ] print(units_per_sku(orders))
When to use it: orders and their lines, invoices and their charges, events and their payload lists, students and their scores. Mistakes to avoid: looping over the record instead of its list; creating the accumulator inside the outer loop, so each record wipes out the last; and return inside the outer loop, which stops after the first record.
- Outer loop over records, inner loop over the list each record holds; the outer record is still available inside.
- A
forover a dictionary visits its keys. Loop over the list stored under a key instead. - Accumulators that cover every record start before the outer loop.
- Next: flatten nested records into plain rows, the shape spreadsheets and CSV files need.