Enrich a list of records by computing a new field from existing ones — here, total = price × qty. The trace shows each record r alongside the computed total, one iteration at a time.

By hand

Loop over the records. Compute total from the current record's fields, then spread the original record plus the new field into a fresh dict with {**r, ...}.

naive.py
Replay: real traced execution (multi-file project)
records = [
    {'n': 'a', 'p': 2, 'q': 5},
    {'n': 'b', 'p': 5, 'q': 6},
    {'n': 'c', 'p': 3, 'q': 7},
    {'n': 'd', 'p': 8, 'q': 3},
    {'n': 'e', 'p': 4, 'q': 8},
    {'n': 'f', 'p': 6, 'q': 9},
]
# trace: ignore records, enriched
enriched = []
for r in records:
    total = r['p'] * r['q']
    new = {**r, 'total': total}
    enriched.append(new)
print('RESULT:', [d['total'] for d in enriched])
  1. {'n': 'a', 'p': 2, 'q': 5},

    1records = [2    {'n': 'a', 'p': 2, 'q': 5},3    {'n': 'b', 'p': 5, 'q': 6},
  2. {'n': 'b', 'p': 5, 'q': 6},

    2{'n': 'a', 'p': 2, 'q': 5},3{'n': 'b', 'p': 5, 'q': 6},4{'n': 'c', 'p': 3, 'q': 7},
  3. {'n': 'c', 'p': 3, 'q': 7},

    3{'n': 'b', 'p': 5, 'q': 6},4{'n': 'c', 'p': 3, 'q': 7},5{'n': 'd', 'p': 8, 'q': 3},
  4. {'n': 'd', 'p': 8, 'q': 3},

    4{'n': 'c', 'p': 3, 'q': 7},5{'n': 'd', 'p': 8, 'q': 3},6{'n': 'e', 'p': 4, 'q': 8},
  5. {'n': 'e', 'p': 4, 'q': 8},

    5{'n': 'd', 'p': 8, 'q': 3},6{'n': 'e', 'p': 4, 'q': 8},7{'n': 'f', 'p': 6, 'q': 9},
  6. {'n': 'f', 'p': 6, 'q': 9},

    6    {'n': 'e', 'p': 4, 'q': 8},7    {'n': 'f', 'p': 6, 'q': 9},8]
  7. records = [

    1records = [2    {'n': 'a', 'p': 2, 'q': 5},
  8. enriched = []

    9# trace: ignore records, enriched10enriched = []11for r in records:
  9. r ← {'n': 'a', 'p': 2, 'q': 5}, total ← 10, new ← {'n': 'a', 'p': 2, 'q': 5, 'total': 10}

    pass 1 of 6
    10enriched = []11for r in records:12    total = r['p'] * r['q']13    new = {**r, 'total': total}14    enriched.append(new)15print('RESULT:', [d['total'] for d in enriched])
    values this step{'n': 'a', 'p': 2, 'q': 5}r10total{'n': 'a', 'p': 2, 'q': 5, 'total': 10}new
    All 6 passes — pass 1 is the card above
    passrtotalnew
    1{'n': 'a', 'p': 2, 'q': 5}10{'n': 'a', 'p': 2, 'q': 5, 'total': 10}
    2{'n': 'a', 'p': 2, 'q': 5} {'n': 'b', 'p': 5, 'q': 6}10 30{'n': 'a', 'p': 2, 'q': 5, 'total': 10} {'n': 'b', 'p': 5, 'q': 6, 'total': 30}
    3{'n': 'b', 'p': 5, 'q': 6} {'n': 'c', 'p': 3, 'q': 7}30 21{'n': 'b', 'p': 5, 'q': 6, 'total': 30} {'n': 'c', 'p': 3, 'q': 7, 'total': 21}
    4{'n': 'c', 'p': 3, 'q': 7} {'n': 'd', 'p': 8, 'q': 3}21 24{'n': 'c', 'p': 3, 'q': 7, 'total': 21} {'n': 'd', 'p': 8, 'q': 3, 'total': 24}
    5{'n': 'd', 'p': 8, 'q': 3} {'n': 'e', 'p': 4, 'q': 8}24 32{'n': 'd', 'p': 8, 'q': 3, 'total': 24} {'n': 'e', 'p': 4, 'q': 8, 'total': 32}
    6{'n': 'e', 'p': 4, 'q': 8} {'n': 'f', 'p': 6, 'q': 9}32 54{'n': 'e', 'p': 4, 'q': 8, 'total': 32} {'n': 'f', 'p': 6, 'q': 9, 'total': 54}
  10. for r in records:

    10enriched = []11for r in records:12    total = r['p'] * r['q']
  11. stdout ← RESULT: [10, 30, 21, 24, 32, 54]

    14    enriched.append(new)15print('RESULT:', [d['total'] for d in enriched])
    values this stepRESULT: [10, 30, 21, 24, 32, 54]stdout

The Pythonic way

A list comprehension with the dict-spread idiom {**r, 'total': r['p'] * r['q']} produces each enriched record in one expression, without an explicit loop or accumulator.

library.py
records = [
    {'n': 'a', 'p': 2, 'q': 5},
    {'n': 'b', 'p': 5, 'q': 6},
    {'n': 'c', 'p': 3, 'q': 7},
    {'n': 'd', 'p': 8, 'q': 3},
    {'n': 'e', 'p': 4, 'q': 8},
    {'n': 'f', 'p': 6, 'q': 9},
]
enriched = [{**r, 'total': r['p'] * r['q']} for r in records]
print('RESULT:', [d['total'] for d in enriched])
RESULT: [10, 30, 21, 24, 32, 54]

Implementation notes

  • records and enriched are excluded from tracing (# trace: ignore) because even two full-dict records push the list repr past 80 characters. The per-step visible state is r (the input record, ~25 chars), total (the computed value), and new (the enriched record with the added field, ~40 chars) — exactly the three variables that teach "add a derived field".
  • {**r, 'total': total} is the standard idiom for non-destructive dict enrichment: it copies every key from r into a new dict and adds 'total'.
  • The enriched.append(new) events are zero-delta in the trace because enriched is ignored; the RESULT line confirms the accumulated output.