CodeMIRAI
0 XP

Counter and defaultdict

2 min read 5 runnable examples Quiz included

The collections module has container types that make common jobs shorter and clearer than plain lists and dictionaries.

Counter: counting things

Python
from collections import Counter

votes = ["Python", "JavaScript", "Python", "SQL", "Python", "JavaScript"]
tally = Counter(votes)
print(tally)
print(tally["Python"])
print(tally.most_common(2))
print(tally["Rust"])              # missing items count as 0, no KeyError

It counts anything iterable, such as the letters in a word:

Python
from collections import Counter

print(Counter("mississippi").most_common())
words = "the cat and the hat and the bat".split()
print(Counter(words).most_common(1))

defaultdict: no more missing keys

A defaultdict creates a default value the first time a missing key is used:

Python
from collections import defaultdict

words = ["apple", "avocado", "banana", "blueberry", "cherry", "apricot"]
by_letter = defaultdict(list)
for w in words:
    by_letter[w[0]].append(w)       # no need to check if the key exists
print(dict(by_letter))

totals = defaultdict(int)           # int() gives 0
for city, amount in [("Pune", 300), ("Delhi", 120), ("Pune", 80)]:
    totals[city] += amount
print(dict(totals))

namedtuple: tuples with field names

Python
from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y)                     # readable names instead of p[0], p[1]
print(p)

Book = namedtuple("Book", "title author year")
b = Book("Clean Code", "Robert C. Martin", 2008)
print(f"{b.title} ({b.year})")

A namedtuple is still a tuple (immutable, unpackable), but self-documenting. For richer records, see the dataclasses lesson.

deque: a fast double-ended queue

A deque ("deck") adds and removes at both ends quickly, which a list can't do at the front:

Python
from collections import deque

queue = deque(["Asha", "Leo"])
queue.append("Mei")          # join at the back
queue.appendleft("VIP")      # jump the queue
print(queue)
print(queue.popleft())       # serve from the front
print(queue)

recent = deque(maxlen=3)     # keeps only the last 3 items
for page in ["home", "about", "blog", "contact", "pricing"]:
    recent.append(page)
print(list(recent))

maxlen makes a deque perfect for "the last N items": recent pages, a moving average, an undo history.

Finished this lesson?Mark it complete to earn +20 XP and move your progress on.