Attach a category label to each product by looking up its code in a side dict. Unknown codes fall back to a default value. The trace shows cat resolving at each step and result accumulating (name, category) pairs, with ('mat', 'other') appearing for the unrecognised code 'z'.

By hand

Iterate over products and codes together. For each pair call categories.get(code, 'other') to resolve the label, then append the (name, cat) tuple to result.

naive.py
Replay: real traced execution (multi-file project)
products = ['pen', 'cup', 'bag', 'mat']
codes = ['a', 'b', 'b', 'z']
categories = {'a': 'work', 'b': 'home'}
result = []
for name, code in zip(products, codes):
    cat = categories.get(code, 'other')
    result.append((name, cat))
print('RESULT:', result)
  1. products ← ['pen', 'cup', 'bag', 'mat']

    1products = ['pen', 'cup', 'bag', 'mat']2codes = ['a', 'b', 'b', 'z']
    values this step['pen', 'cup', 'bag', 'mat']products
  2. codes ← ['a', 'b', 'b', 'z']

    1products = ['pen', 'cup', 'bag', 'mat']2codes = ['a', 'b', 'b', 'z']3categories = {'a': 'work', 'b': 'home'}
    values this step['a', 'b', 'b', 'z']codes
  3. categories ← {'a': 'work', 'b': 'home'}

    2codes = ['a', 'b', 'b', 'z']3categories = {'a': 'work', 'b': 'home'}4result = []
    values this step{'a': 'work', 'b': 'home'}categories
  4. result ← []

    3categories = {'a': 'work', 'b': 'home'}4result = []5for name, code in zip(products, codes):
    values this step[]result
  5. code ← 'a', name ← 'pen'

    4result = []5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')
    values this step'a'code'pen'name
  6. cat ← 'work'

    5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')7    result.append((name, cat))
    values this step'work'cat
  7. result ← [('pen', 'work')]

    6    cat = categories.get(code, 'other')7    result.append((name, cat))8print('RESULT:', result)
    values this step[] [('pen', 'work')]result
  8. code ← 'b', name ← 'cup'

    4result = []5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')
    values this step'a' 'b'code'pen' 'cup'name
  9. cat ← 'home'

    5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')7    result.append((name, cat))
    values this step'work' 'home'cat
  10. result ← [('pen', 'work'), ('cup', 'home')]

    6    cat = categories.get(code, 'other')7    result.append((name, cat))8print('RESULT:', result)
    values this step[('pen', 'work')] [('pen', 'work'), ('cup', 'home')]result
  11. name ← 'bag'

    4result = []5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')
    values this step'cup' 'bag'name
  12. cat = categories.get(code, 'other')

    5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')7    result.append((name, cat))
  13. result ← [('pen', 'work'), ('cup', 'home'), ('bag', 'home')]

    6    cat = categories.get(code, 'other')7    result.append((name, cat))8print('RESULT:', result)
    values this step[('pen', 'work'), ('cup', 'home')] [('pen', 'work'), ('cup', 'home'), ('bag', 'home')]result
  14. code ← 'z', name ← 'mat'

    4result = []5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')
    values this step'b' 'z'code'bag' 'mat'name
  15. cat ← 'other'

    5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')7    result.append((name, cat))
    values this step'home' 'other'cat
  16. result ← [('pen', 'work'), ('cup', 'home'), ('bag', 'home'), ('mat', 'other')]

    6    cat = categories.get(code, 'other')7    result.append((name, cat))8print('RESULT:', result)
    values this step[('pen', 'work'), ('cup', 'home'), ('bag', 'home')] [('pen', 'work'), ('cup', 'home'), ('bag', 'home'), ('mat', 'other')]result
  17. for name, code in zip(products, codes):

    4result = []5for name, code in zip(products, codes):6    cat = categories.get(code, 'other')
  18. stdout ← RESULT: [('pen', 'work'), ('cup', 'home'), ('bag', 'home'), ('mat', 'other')]

    7    result.append((name, cat))8print('RESULT:', result)
    values this stepRESULT: [('pen', 'work'), ('cup', 'home'), ('bag', 'home'), ('mat', 'other')]stdout

The Pythonic way

A list comprehension folds the lookup and the pairing into one expression. The get call with its default handles unknown codes inline.

library.py
products = ['pen', 'cup', 'bag', 'mat']
codes = ['a', 'b', 'b', 'z']
categories = {'a': 'work', 'b': 'home'}
result = [(name, categories.get(code, 'other'))
          for name, code in zip(products, codes)]
print('RESULT:', result)
RESULT: [('pen', 'work'), ('cup', 'home'), ('bag', 'home'), ('mat', 'other')]

Implementation notes

  • This is the everyday "attach a label" pattern — a special case of a left join where the right table is a flat key→value dict rather than a record table. Row count is always preserved because every code produces a value (matched or default).
  • The equivalent pandas operation is df['cat'] = df['code'].map(categories) or .map(categories).fillna('other') — see the python-pandas track lesson map-lookup-column for the API form.
  • Unlike left-join-with-missing, the fallback is a real label ('other') rather than None, so downstream code does not need a None-guard.