
When I first started coding Python, I wasn’t aware of some of the standard library capabilities, especially the collections package.
Fast forward like 5 or 6 years later, I started exploring the collections package more deeply to try and understand why it’s worth looking into and using.
After working with some of the data structures, I want to share my top 2 most used ones (plus an honorable mention) that I still use to this day.
Counting using the Counter class
We both know counting is hard. Lucky for us, computers are really good at counting. So when we’re needing to count items, we don’t want to be writing code to do this:
words = ["hello", "hello", "goodbye", "goodbye", "yes", "no"]
word_counts = {}
for word in words:
if word in word_counts:
word_counts[word] += 1
else:
word_counts[word] = 1Instead, we’re going to want to import the Counter class and count this way:
from collections import Counter
counts = Counter(words)There’s 3 clear advantages with using Counter instead of your home-cooked solution:
The code is much cleaner - it’s 3 lines versus 6.
The built-in method is the more in line with the “object oriented” approach to writing code.
The underlying implementation is written in C, so it runs with a lower constant factor than a Python-level
if/elseloop. On a list of 100 you won’t notice the performance, but on a million, you will.
namedtuples: Tuples with a name
Say that you have a list of users you’ve pulled from your database, and you’re looking to send them an email:
users = [
(100, "alice", "[email protected]", "admin"),
(101, "bob", "[email protected]", "viewer"),
(102, "carol", "[email protected]", "editor"),
]
for user in users:
if user[3] == "admin":
send_email(user[2])When it comes to debugging, this can get complicated: who’s user[3] and what field is user[3]? Is user[2] the email? In this example, it’s easy to track down; however, when scaled it could be a nightmare to try and debug
You could use a dataclass to help with this:
from dataclasses import dataclass
@dataclass
class User:
user_id : int
name : str
email : str
role : strBut a namedtuple might fit this scenario a little better:
from collections import namedtuple
User = namedtuple("User", ["user_id", "name", "email", "role"])
users = [
User("usr_42", "alice", "[email protected]", "admin"),
User("usr_78", "bob", "[email protected]", "viewer"),
User("usr_91", "carol", "[email protected]", "editor"),
]
for user in users:
if user.role == "admin":
send_email(user.email)There’s a few reasons why I think a namedtuple would be better in this kind of situation:
Unlike dataclasses, namedtuples are immutable.
The original code was a list of tuples -
namedtuplesare a drop-in replacement for existing code. Using a dataclass would require a slight rewrite.
Honorable mention: OrderedDict
Prior to Python 3.7, built-in dictionaries didn't maintain order. That is, when you inserted a key/value pair, it wouldn’t know when you inserted it - all it would know is that it exists in the dictionary.
Python 3.1 introduced OrderedDict that solved this problem. The most common example of this is a LRU cache:
from collections import OrderedDict
cache = OrderedDict()
def add_to_cache(key, value, max_size=100):
cache[key] = value
if len(cache) > max_size:
cache.popitem(last=False)
def get_from_cache(key):
if key in cache:
cache.move_to_end(key) # mark as recently used
return cache[key]
return NoneBut with the changed behavior, OrderedDicts were kind of phased out. They’re still used to be able to re-oder entries and perform order-sensitive equality checks (such as comparing configuration files or API responses).
What other parts of the collections library do you use? Reply to this email and let me know!
Happy coding!
📧 Join the Python Snacks Newsletter! 🐍
Want even more Python-related content that’s useful? Here’s 3 reasons why you should subscribe the Python Snacks newsletter:
Get Ahead in Python with bite-sized Python tips and tricks delivered straight to your inbox, like the one above.
Exclusive Subscriber Perks: Receive a curated selection of up to 6 high-impact Python resources, tips, and exclusive insights with each email.
Get Smarter with Python in under 5 minutes. Your next Python breakthrough could just an email away.
You can unsubscribe at any time.
Interested in starting a newsletter or a blog?
Do you have a wealth of knowledge and insights to share with the world? Starting your own newsletter or blog is an excellent way to establish yourself as an authority in your field, connect with a like-minded community, and open up new opportunities.
If TikTok, Twitter, Facebook, or other social media platforms were to get banned, you’d lose all your followers. This is why you should start a newsletter: you own your audience.
This article may contain affiliate links. Affiliate links come at no cost to you and support the costs of this blog. Should you purchase a product/service from an affiliate link, it will come at no additional cost to you.

