Accumulate numeric totals per category from parallel label and value lists. Each new category is seeded at 0 the first time it is seen; subsequent visits add to the existing total. The trace shows sums growing and updating one step at a time.

By hand

Walk cats and vals together with zip. For each pair, seed sums[cat] to 0 if the key has not been seen before, then add val to it.

naive.py
Replay: real traced execution (multi-file project)
cats = ['a', 'b', 'a', 'c', 'b', 'a', 'b', 'c']
vals = [3, 5, 7, 2, 8, 4, 6, 9]
sums = {}
for cat, val in zip(cats, vals):
    if cat not in sums:
        sums[cat] = 0
    sums[cat] = sums[cat] + val
print('RESULT:', {k: sums[k] for k in sorted(sums)})
  1. cats ← ['a', 'b', 'a', 'c', 'b', 'a', 'b', 'c']

    1cats = ['a', 'b', 'a', 'c', 'b', 'a', 'b', 'c']2vals = [3, 5, 7, 2, 8, 4, 6, 9]
    values this step['a', 'b', 'a', 'c', 'b', 'a', 'b', 'c']cats
  2. vals ← [3, 5, 7, 2, 8, 4, 6, 9]

    1cats = ['a', 'b', 'a', 'c', 'b', 'a', 'b', 'c']2vals = [3, 5, 7, 2, 8, 4, 6, 9]3sums = {}
    values this step[3, 5, 7, 2, 8, 4, 6, 9]vals
  3. sums ← {}

    2vals = [3, 5, 7, 2, 8, 4, 6, 9]3sums = {}4for cat, val in zip(cats, vals):
    values this step{}sums
  4. cat ← 'a', val ← 3, sums ← {'a': 3}

    pass 1 of 2
    3sums = {}4for cat, val in zip(cats, vals):5    if cat not in sums:6        sums[cat] = 07    sums[cat] = sums[cat] + val8print('RESULT:', {k: sums[k] for k in sorted(sums)})
    values this step'a'cat3val{'a': 0} {'a': 3}sums
  5. cat ← 'b', val ← 5, sums ← {'a': 3, 'b': 5}

    pass 2 of 2
    3sums = {}4for cat, val in zip(cats, vals):5    if cat not in sums:6        sums[cat] = 07    sums[cat] = sums[cat] + val8print('RESULT:', {k: sums[k] for k in sorted(sums)})
    values this step'a' 'b'cat3 5val{'a': 3, 'b': 0} {'a': 3, 'b': 5}sums
  6. cat ← 'a', val ← 7

    3sums = {}4for cat, val in zip(cats, vals):5    if cat not in sums:
    values this step'b' 'a'cat5 7val
  7. if cat not in sums:

    4for cat, val in zip(cats, vals):5    if cat not in sums:6        sums[cat] = 0
  8. sums ← {'a': 10, 'b': 5}

    6        sums[cat] = 07    sums[cat] = sums[cat] + val8print('RESULT:', {k: sums[k] for k in sorted(sums)})
    values this step{'a': 3, 'b': 5} {'a': 10, 'b': 5}sums
  9. cat ← 'c', val ← 2

    3sums = {}4for cat, val in zip(cats, vals):5    if cat not in sums:
    values this step'a' 'c'cat7 2val
  10. if cat not in sums:

    4for cat, val in zip(cats, vals):5    if cat not in sums:6        sums[cat] = 0
  11. sums ← {'a': 10, 'b': 5, 'c': 0}

    5if cat not in sums:6    sums[cat] = 07sums[cat] = sums[cat] + val
    values this step{'a': 10, 'b': 5} {'a': 10, 'b': 5, 'c': 0}sums
  12. sums ← {'a': 10, 'b': 5, 'c': 2}, cat ← 'b', val ← 8

    pass 1 of 4
    3sums = {}4for cat, val in zip(cats, vals):5    if cat not in sums:6        sums[cat] = 07    sums[cat] = sums[cat] + val8print('RESULT:', {k: sums[k] for k in sorted(sums)})
    values this step{'a': 10, 'b': 5, 'c': 0} {'a': 10, 'b': 5, 'c': 2}sums'c' 'b'cat2 8val
    All 4 passes — pass 1 is the card above
    passsumscatval
    1{'a': 10, 'b': 5, 'c': 0} {'a': 10, 'b': 5, 'c': 2}'c' 'b'2 8
    2{'a': 10, 'b': 5, 'c': 2} {'a': 10, 'b': 13, 'c': 2}'b' 'a'8 4
    3{'a': 10, 'b': 13, 'c': 2} {'a': 14, 'b': 13, 'c': 2}'a' 'b'4 6
    4{'a': 14, 'b': 13, 'c': 2} {'a': 14, 'b': 19, 'c': 2}'b' 'c'6 9
  13. sums ← {'a': 14, 'b': 19, 'c': 11}

    6        sums[cat] = 07    sums[cat] = sums[cat] + val8print('RESULT:', {k: sums[k] for k in sorted(sums)})
    values this step{'a': 14, 'b': 19, 'c': 2} {'a': 14, 'b': 19, 'c': 11}sums
  14. for cat, val in zip(cats, vals):

    3sums = {}4for cat, val in zip(cats, vals):5    if cat not in sums:
  15. stdout ← RESULT: {'a': 14, 'b': 19, 'c': 11}

    7    sums[cat] = sums[cat] + val8print('RESULT:', {k: sums[k] for k in sorted(sums)})
    values this stepRESULT: {'a': 14, 'b': 19, 'c': 11}stdout

The Pythonic way

defaultdict(int) auto-initialises any new key to 0, eliminating the explicit seed check. The loop body shrinks to a single += line.

library.py
from collections import defaultdict
cats = ['a', 'b', 'a', 'c', 'b', 'a', 'b', 'c']
vals = [3, 5, 7, 2, 8, 4, 6, 9]
sums = defaultdict(int)
for cat, val in zip(cats, vals):
    sums[cat] += val
print('RESULT:', {k: sums[k] for k in sorted(sums)})
RESULT: {'a': 14, 'b': 19, 'c': 11}

Implementation notes

  • dict.get(k, 0) + v is an alternative to defaultdict: write sums[cat] = sums.get(cat, 0) + val to avoid the seed branch entirely.
  • sums is printed via {k: sums[k] for k in sorted(sums)} to give alphabetical key order regardless of insertion order.
  • The if cat not in sums events are zero-delta in the trace; the key state change appears on the sums[cat] = 0 or sums[cat] = sums[cat] + val line.