Dictionaries as Tables
Frequency Count
Count how many times each label appears in a sequence, building a frequency
table as a dict. The trace shows counts seeding a new key at 1 on the
first occurrence of each label and incrementing it on every repeat.
By hand
Walk the labels. For each one, check whether it is already in counts: if
so, increment; if not, seed it at 1. Print the result with sorted keys for
a deterministic frequency table.
naive.py
Replay: real traced execution (multi-file project)
labels = ['b', 'r', 'g', 'b', 'r', 'b', 'g', 'r', 'b']
counts = {}
for x in labels:
if x in counts:
counts[x] = counts[x] + 1
else:
counts[x] = 1
print('RESULT:', {k: counts[k] for k in sorted(counts)})
labels ← ['b', 'r', 'g', 'b', 'r', 'b', 'g', 'r', 'b']
1labels = ['b', 'r', 'g', 'b', 'r', 'b', 'g', 'r', 'b']2counts = {}values this step['b', 'r', 'g', 'b', 'r', 'b', 'g', 'r', 'b']labelscounts ← {}
1labels = ['b', 'r', 'g', 'b', 'r', 'b', 'g', 'r', 'b']2counts = {}3for x in labels:values this step{}countsx ← 'b', counts ← {'b': 1}
pass 1 of 32counts = {}3for x in labels:4 if x in counts:5 counts[x] = counts[x] + 16 else:7 counts[x] = 18print('RESULT:', {k: counts[k] for k in sorted(counts)})values this step'b'x{} → {'b': 1}countsAll 3 passes — pass 1 is the card above pass xcounts1 'b' {} → {'b': 1} 2 'b' → 'r' {'b': 1} → {'b': 1, 'r': 1} 3 'r' → 'g' {'b': 1, 'r': 1} → {'b': 1, 'r': 1, 'g': 1} x ← 'b', counts ← {'b': 2, 'r': 1, 'g': 1}
pass 1 of 62counts = {}3for x in labels:4 if x in counts:5 counts[x] = counts[x] + 16 else:values this step'g' → 'b'x{'b': 1, 'r': 1, 'g': 1} → {'b': 2, 'r': 1, 'g': 1}countsAll 6 passes — pass 1 is the card above pass xcounts1 'g' → 'b' {'b': 1, 'r': 1, 'g': 1} → {'b': 2, 'r': 1, 'g': 1} 2 'b' → 'r' {'b': 2, 'r': 1, 'g': 1} → {'b': 2, 'r': 2, 'g': 1} 3 'r' → 'b' {'b': 2, 'r': 2, 'g': 1} → {'b': 3, 'r': 2, 'g': 1} 4 'b' → 'g' {'b': 3, 'r': 2, 'g': 1} → {'b': 3, 'r': 2, 'g': 2} 5 'g' → 'r' {'b': 3, 'r': 2, 'g': 2} → {'b': 3, 'r': 3, 'g': 2} 6 'r' → 'b' {'b': 3, 'r': 3, 'g': 2} → {'b': 4, 'r': 3, 'g': 2} for x in labels:
2counts = {}3for x in labels:4 if x in counts:stdout ← RESULT: {'b': 4, 'g': 2, 'r': 3}
7 counts[x] = 18print('RESULT:', {k: counts[k] for k in sorted(counts)})values this stepRESULT: {'b': 4, 'g': 2, 'r': 3}stdout
The Pythonic way
Counter builds the frequency table in one call and sorts by frequency in
.most_common(), making it easy to see the most frequent labels at a glance.
library.py
from collections import Counter
labels = ['b', 'r', 'g', 'b', 'r', 'b', 'g', 'r', 'b']
counts = Counter(labels)
top = counts.most_common()
print('most common:', top)
print('RESULT:', {k: counts[k] for k in sorted(counts)})
most common: [('b', 4), ('r', 3), ('g', 2)]
RESULT: {'b': 4, 'g': 2, 'r': 3}
Implementation notes
- This lesson shares its mechanism with
python-data-basics/group-count(ch04). The distinction is framing: group-count aggregates a value column per category; frequency-count builds a frequency table over a flat label sequence. The hand-written pattern is identical in both cases. Counteris a subclass ofdict, socounts[k]works just like a regular dict lookup after construction..most_common()with no argument returns all entries sorted by count descending;.most_common(n)returns only the top n.- The
if x in counts / elsepattern is equivalent tocounts[x] = counts.get(x, 0) + 1— both are common; the explicit branch makes the seed-then-increment logic visible in the trace.