A few days ago, I submitted my first major Python assignment, a fully working Hangman game. It had two game modes, ASCII art gallows, screen clearing, and a built-in word list. I was proud of it. Then I learnt about Python's collections library, and I realized I could make the game smarter, more fun, and more educational without rewriting everything from scratch. This post walks through what a collections library is, what I learnt, and exactly how I used it to upgrade Hangman.
What is the collections Library?
Python comes with a module called collections that is part of the Standard Library, meaning it ships with Python, and you never need to install anything extra. It gives you upgraded versions of Python's basic containers like lists, tuples, and dictionaries, each one designed to solve a specific problem more cleanly than doing it yourself.
You import what you need like this:
from collections import Counter, defaultdict
The two tools I used in this upgrade are Counter and defaultdict. Here is what each one does.
Counter — Count Anything Instantly
Counter takes any sequence, a string, a list, anything, and returns a dictionary where each item is a key, and its count is the value. What makes it especially powerful is the most_common() method, which sorts items from most frequent to least frequent automatically.
letter_counts = Counter("mississippi") print(letter_counts.most_common(3)) # [('i', 4), ('s', 4), ('p', 2)]
defaultdict — A Dictionary That Never Crashes
A normal Python dictionary throws a KeyError if you try to access a key that does not exist yet. defaultdict solves this by automatically creating a default value for any new key the moment you access it. You tell it what type of default to use: list, int, set, and so on.
groups = defaultdict(list) groups["fruits"].append("apple") # no crash!
How I Upgraded the Hangman Game
I made two targeted improvements, one using each tool. Neither one changed how the core game works; they just made it smarter and more enjoyable.
Upgrade 1: Word Length Selection with defaultdict
Before the upgrade, in one-player mode, the computer just picked a completely random word. You had no control over the difficulty. Now, when the program starts, it runs this code once to organize all 20 words into groups by their length:
words_by_length = defaultdict(list) for w in WORDS: words_by_length[len(w)].append(w)
The result is a dictionary that looks like this: {6: ["python", "dolphin"], 8: ["computer", "keyboard", "elephant"], 9: ["adventure"]}. Now, when you start a game, you are shown all available word lengths and can pick one. Want an easy round? Pick 6 letters. Want a challenge? Pick 11. The computer then picks randomly from only words that match your chosen length.
What I found clever about this is that the defaultdict does all the sorting work in just two lines. Without it, I would have had to write a longer if-else block to check whether each length key existed before appending to it.
Upgrade 2: A Letter Frequency Hint System with Counter
The second upgrade adds a hint system. At any point during the game, instead of guessing a letter, you can type --hint. The game then uses Counter to analyze which letters are still unguessed in the word and tells you how many times the most frequent one appears without revealing what the letter actually is. You get three hints per game.
letter_counts = Counter(word)
unguessed = {l: c for l, c in letter_counts.items()if l not in guessed_letters}
most_common_letter, count = Counter(unguessed).most_common(1)[0]
So if the word is "programming" and you have already guessed 'g' and 'r', the hint might say: "the most frequent remaining letter appears 3 times in the word." That is a meaningful clue without giving away the answer. It changes the game from pure guessing into a small puzzle about letter frequency.
What I Learnt From This Upgrade
Three things really stuck with me from doing this:
• The Standard Library is huge and already solves most common problems. Before this, I thought you always had to write your own logic for things like counting and grouping. Collections showed me that Python often has a cleaner built-in solution.
• Small additions can change the feel of a program significantly. Adding word length selection and hints did not rewrite the game at all, but they made it feel much more complete and professional.
• DRY (Don't Repeat Yourself) matters. defaultdict let me replace what would have been several repeated if-checks with two clean lines. That is the kind of thing that makes code easier to read and maintain.
What's Next?
I am still early in my Python journey, but projects like this are making it click a lot faster than just reading theory. Next, I want to explore more of the Standard Library. There is a module called itertools that looks very interesting for working with loops, and datetime for handling time-based logic. I will write about those when I get there.
Thanks for reading — BUOYAFI
Top comments (0)