2 minutes
Supercharging Data Structures with the collections Module
Welcome to part one of our Python 3 features series! Today, we’re diving into the handy tools in the collections
module that can make your code cleaner and faster.
Python’s built-in containers (list
, dict
, set
, tuple
) are great, but sometimes you need a bit more power. Enter the collections
module:
1. deque
: Double-Ended Queue
A deque
lets you push and pop from both ends in constant time. Perfect for queues, sliding windows, or undo/redo stacks.
from collections import deque
dq = deque([1, 2, 3])
dq.append(4) # add at right
q.appendleft(0) # add at left
print(dq) # deque([0, 1, 2, 3, 4])
dq.pop() # remove right end -> 4
dq.popleft() # remove left end -> 0
2. Counter
: Quick Counts
Want to tally up items? Counter
counts each element for you.
from collections import Counter
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
c = Counter(words)
print(c) # Counter({'apple': 3, 'banana': 2, 'orange': 1})
print(c.most_common(2)) # [('apple', 3), ('banana', 2)]
You can even add or subtract Counters, which is great for comparing two sets of data.
3. defaultdict
: No More KeyErrors
With a defaultdict
, you give a factory for missing keys, no more KeyError
surprises.
from collections import defaultdict
d = defaultdict(int)
for ch in 'banana':
d[ch] += 1
print(d) # {'b': 1, 'a': 3, 'n': 2}
# Use any factory you like
dd = defaultdict(list)
dd['letters'].append('a')
print(dd) # {'letters': ['a']}
4. OrderedDict
: Control Your Order
Before Python 3.7, regular dicts didn’t keep order. Even now, OrderedDict
gives you extra tricks like moving items around.
from collections import OrderedDict
od = OrderedDict(a=1, b=2, c=3)
od.move_to_end('a')
print(od) # OrderedDict([('b', 2), ('c', 3), ('a', 1)])
Handy for LRU caches or any time you need to shuffle the order.
5. namedtuple
: Readable, Lightweight Records
Need a simple class to bundle data? namedtuple
gives you fields with almost zero overhead.
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 10 20
print(p) # Point(x=10, y=20)
You get tuple behaviors plus named access, and it’s immutable!
That’s it for a quick tour of collections
. Next time, we’ll see how yield from
and enhanced generators can level up your code. Happy coding!