Build a code-to-name lookup dictionary from two parallel lists, then resolve a batch of query codes — including one that is absent — using a guarded membership test. The trace shows lookup growing one entry at a time and result accumulating found names and the fallback value.

By hand

Walk codes and names together with zip, assigning each pair into lookup. Then iterate over the query codes: test membership with in before accessing, and append a fallback string when the code is missing.

naive.py
Replay: real traced execution (multi-file project)
codes = ['r', 'g', 'b', 'y', 'w']
names = ['red', 'green', 'blue', 'yellow', 'white']
lookup = {}
for code, name in zip(codes, names):
    lookup[code] = name
queries = ['r', 'b', 'x', 'y']
result = []
for q in queries:
    if q in lookup:
        result.append(lookup[q])
    else:
        result.append('unknown')
print('RESULT:', result)
  1. codes ← ['r', 'g', 'b', 'y', 'w']

    1codes = ['r', 'g', 'b', 'y', 'w']2names = ['red', 'green', 'blue', 'yellow', 'white']
    values this step['r', 'g', 'b', 'y', 'w']codes
  2. names ← ['red', 'green', 'blue', 'yellow', 'white']

    1codes = ['r', 'g', 'b', 'y', 'w']2names = ['red', 'green', 'blue', 'yellow', 'white']3lookup = {}
    values this step['red', 'green', 'blue', 'yellow', 'white']names
  3. lookup ← {}

    2names = ['red', 'green', 'blue', 'yellow', 'white']3lookup = {}4for code, name in zip(codes, names):
    values this step{}lookup
  4. code ← 'r', name ← 'red'

    3lookup = {}4for code, name in zip(codes, names):5    lookup[code] = name
    values this step'r'code'red'name
  5. lookup ← {'r': 'red'}

    4for code, name in zip(codes, names):5    lookup[code] = name6queries = ['r', 'b', 'x', 'y']
    values this step{} {'r': 'red'}lookup
  6. code ← 'g', name ← 'green'

    3lookup = {}4for code, name in zip(codes, names):5    lookup[code] = name
    values this step'r' 'g'code'red' 'green'name
  7. lookup ← {'r': 'red', 'g': 'green'}

    4for code, name in zip(codes, names):5    lookup[code] = name6queries = ['r', 'b', 'x', 'y']
    values this step{'r': 'red'} {'r': 'red', 'g': 'green'}lookup
  8. code ← 'b', name ← 'blue'

    3lookup = {}4for code, name in zip(codes, names):5    lookup[code] = name
    values this step'g' 'b'code'green' 'blue'name
  9. lookup ← {'r': 'red', 'g': 'green', 'b': 'blue'}

    4for code, name in zip(codes, names):5    lookup[code] = name6queries = ['r', 'b', 'x', 'y']
    values this step{'r': 'red', 'g': 'green'} {'r': 'red', 'g': 'green', 'b': 'blue'}lookup
  10. code ← 'y', name ← 'yellow'

    3lookup = {}4for code, name in zip(codes, names):5    lookup[code] = name
    values this step'b' 'y'code'blue' 'yellow'name
  11. lookup ← {'r': 'red', 'g': 'green', 'b': 'blue', 'y': 'yellow'}

    4for code, name in zip(codes, names):5    lookup[code] = name6queries = ['r', 'b', 'x', 'y']
    values this step{'r': 'red', 'g': 'green', 'b': 'blue'} {'r': 'red', 'g': 'green', 'b': 'blue', 'y': 'yellow'}lookup
  12. code ← 'w', name ← 'white'

    3lookup = {}4for code, name in zip(codes, names):5    lookup[code] = name
    values this step'y' 'w'code'yellow' 'white'name
  13. lookup ← {'r': 'red', 'g': 'green', 'b': 'blue', 'y': 'yellow', 'w': 'white'}

    4for code, name in zip(codes, names):5    lookup[code] = name6queries = ['r', 'b', 'x', 'y']
    values this step{'r': 'red', 'g': 'green', 'b': 'blue', 'y': 'yellow'} {'r': 'red', 'g': 'green', 'b': 'blue', 'y': 'yellow', 'w': 'white'}lookup
  14. for code, name in zip(codes, names):

    3lookup = {}4for code, name in zip(codes, names):5    lookup[code] = name
  15. queries ← ['r', 'b', 'x', 'y']

    5    lookup[code] = name6queries = ['r', 'b', 'x', 'y']7result = []
    values this step['r', 'b', 'x', 'y']queries
  16. result ← []

    6queries = ['r', 'b', 'x', 'y']7result = []8for q in queries:
    values this step[]result
  17. q ← 'r'

    7result = []8for q in queries:9    if q in lookup:
    values this step'r'q
  18. if q in lookup:

    8for q in queries:9    if q in lookup:10        result.append(lookup[q])
  19. result ← ['red']

    9if q in lookup:10    result.append(lookup[q])11else:
    values this step[] ['red']result
  20. q ← 'b'

    7result = []8for q in queries:9    if q in lookup:
    values this step'r' 'b'q
  21. if q in lookup:

    8for q in queries:9    if q in lookup:10        result.append(lookup[q])
  22. result ← ['red', 'blue']

    9if q in lookup:10    result.append(lookup[q])11else:
    values this step['red'] ['red', 'blue']result
  23. q ← 'x'

    7result = []8for q in queries:9    if q in lookup:
    values this step'b' 'x'q
  24. if q in lookup:

    8for q in queries:9    if q in lookup:10        result.append(lookup[q])
  25. result ← ['red', 'blue', 'unknown']

    11    else:12        result.append('unknown')13print('RESULT:', result)
    values this step['red', 'blue'] ['red', 'blue', 'unknown']result
  26. q ← 'y'

    7result = []8for q in queries:9    if q in lookup:
    values this step'x' 'y'q
  27. if q in lookup:

    8for q in queries:9    if q in lookup:10        result.append(lookup[q])
  28. result ← ['red', 'blue', 'unknown', 'yellow']

    9if q in lookup:10    result.append(lookup[q])11else:
    values this step['red', 'blue', 'unknown'] ['red', 'blue', 'unknown', 'yellow']result
  29. for q in queries:

    7result = []8for q in queries:9    if q in lookup:
  30. stdout ← RESULT: ['red', 'blue', 'unknown', 'yellow']

    12        result.append('unknown')13print('RESULT:', result)
    values this stepRESULT: ['red', 'blue', 'unknown', 'yellow']stdout

The Pythonic way

Write lookup as a dict literal and replace the if/else guard with lookup.get(q, 'unknown'), which returns the fallback value in one expression without a separate membership test.

library.py
lookup = {
    'r': 'red', 'g': 'green', 'b': 'blue',
    'y': 'yellow', 'w': 'white',
}
queries = ['r', 'b', 'x', 'y']
result = [lookup.get(q, 'unknown') for q in queries]
print('RESULT:', result)
RESULT: ['red', 'blue', 'unknown', 'yellow']

Implementation notes

  • d.get(key, default) is preferred over if key in d: d[key] when you only need the value and not the key's presence for branching; it is also slightly faster because it avoids a second hash lookup.
  • Dict lookup is O(1) average-case regardless of size, making it efficient for large tables where a linear list scan would be O(n).
  • Key order in Python dicts is insertion order (guaranteed since 3.7); the trace shows lookup entries appearing in the order they were inserted.