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
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)})

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.
  • Counter is a subclass of dict, so counts[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 / else pattern is equivalent to counts[x] = counts.get(x, 0) + 1 — both are common; the explicit branch makes the seed-then-increment logic visible in the trace.