← Back to Blog

Two Tools That Make Dicts Smarter

The idea

You know dicts. You know how to build them, read them, modify them.

The collections module has two tools that extend what dicts can do — and eliminate two patterns you've probably already written by hand.

Counter — count everything automatically

You have a list. You want to know how many times each value appears.

The manual way:

scores = [85, 74, 85, 91, 85, 74]
counts = {}
for score in scores:
    if score in counts:
        counts[score] += 1
    else:
        counts[score] = 1
print(counts)

The Counter way:

from collections import Counter

scores = [85, 74, 85, 91, 85, 74]
counts = Counter(scores)
print(counts)

Output → Counter({85: 3, 74: 2, 91: 1})

One line. Same result. Sorted by frequency automatically.

Counter works on any iterable — lists, strings, tuples:

letters = Counter("redhorndev")
print(letters)
# Counter({'r': 2, 'e': 2, 'd': 2, 'h': 1, 'o': 1, 'n': 1, 'v': 1})

Counter — useful methods

from collections import Counter

scores = [85, 74, 85, 91, 85, 74, 63]
counts = Counter(scores)

print(counts[85])               # 3 — how many times 85 appears
print(counts[99])               # 0 — missing key returns 0, not KeyError
print(counts.most_common(2))    # [(85, 3), (74, 2)] — top 2

most_common(n) returns the n most frequent elements as a list of tuples.

Missing keys return 0 — never a KeyError.

defaultdict — no more "key might not exist"

You want to group soldiers by squad. The manual way:

squads = {}
assignments = [("Alpha", "Raven"), ("Bravo", "Wolf"), ("Alpha", "Ghost")]

for squad, soldier in assignments:
    if squad not in squads:
        squads[squad] = []
    squads[squad].append(soldier)

print(squads)

The defaultdict way:

from collections import defaultdict

squads = defaultdict(list)
assignments = [("Alpha", "Raven"), ("Bravo", "Wolf"), ("Alpha", "Ghost")]

for squad, soldier in assignments:
    squads[squad].append(soldier)

print(dict(squads))

Output → {'Alpha': ['Raven', 'Ghost'], 'Bravo': ['Wolf']}

When you access a key that doesn't exist, defaultdict creates it automatically with the default value — here, an empty list.

You pass the type as the argument: defaultdict(list), defaultdict(int), defaultdict(set).

from collections import defaultdict

word_count = defaultdict(int)
words = ["bull", "raven", "bull", "ghost", "bull"]

for word in words:
    word_count[word] += 1

print(dict(word_count))
# {'bull': 3, 'raven': 1, 'ghost': 1}

defaultdict(int) starts every new key at 0 — no check needed before incrementing.

Heads up!

  • Counter is a subclass of dict — all dict methods work on it
  • Missing keys in Counter return 0 — not KeyError
  • defaultdict creates missing keys automatically — be aware if you check in after accessing
  • Wrap in dict() when printing defaultdict for cleaner output

What you should understand now

  • Counter(iterable) counts occurrences of each element
  • Counter.most_common(n) returns the n most frequent elements
  • Missing keys in Counter return 0
  • defaultdict(type) creates missing keys with a default value automatically
  • Both eliminate boilerplate patterns you'd otherwise write by hand
[ login to bookmark ] // copied! 18 views · 2 min
// resources
Code Example module_collections.py
← prev Timing Your Code with the time Module next → Built-in String Constants
// 0 comments
// No comments yet. Be the first.
// leave a comment

// Your comment will appear after approval.