Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
228: Collections Module: defaultdict
Imagine you're sorting a massive pile of physical mail into folders. Every time you pick up a letter, you look at the recipient's name. With a standard dictionary approach, your process looks like this: "Is there already a folder for 'John Doe'? No? Okay, I need to stop what I'm doing, go to the supply cabinet, grab a brand new empty folder, write 'John Doe' on the tab, put it on the desk, and then put the letter inside."
It's tedious. You're spending half your time managing the folders rather than actually sorting the mail.
A defaultdict is like having a magic desk. Whenever you try to put a letter into a folder that doesn't exist, the desk instantly manifests a brand new, empty folder for that person the millisecond you reach for it. You don't have to check if it's there; you just act as if it always has been.
Stopping the KeyError Cycle
If you've been using standard dictionaries to group data, you've probably written this pattern a hundred times:
# The old, clunky way
user_groups = {}
users = [('admin', 'Alice'), ('editor', 'Bob'), ('admin', 'Charlie')]
for role, name in users:
if role not in user_groups:
user_groups[role] = []
user_groups[role].append(name)
I'll be honest: that if role not in user_groups check is noise. It doesn't describe what your code is doing; it just manages a limitation of the dictionary. This is exactly where defaultdict from the collections module shines. It lets you skip the check entirely.
from collections import defaultdict
# We tell defaultdict that if a key is missing, it should call list() to create a value
user_groups = defaultdict(list)
users = [('admin', 'Alice'), ('editor', 'Bob'), ('admin', 'Charlie')]
for role, name in users:
# No if-statement needed. If 'admin' isn't there, Python creates [] automatically.
user_groups[role].append(name)
The "Factory" is the Key
Notice that I passed list into defaultdict(). I didn't pass an empty list []; I passed the function (or type) that creates a list. This is called a "default factory."
You can use different factories depending on what you're trying to achieve. I've found these three to be the most useful in real-world projects:
defaultdict(list): Great for grouping items (like the example above).defaultdict(int): Perfect for counting. Sinceint()returns 0, you can start incrementing immediately:counts[item] += 1.defaultdict(set): Use this when you want to group items but ensure there are no duplicates in each group.
One thing to keep in mind: defaultdict creates the entry the moment you access it. If you try to print a key that doesn't exist, defaultdict won't throw an error—it will simply create that key with the default value and return it. This is usually a feature, but it can occasionally lead to "bloated" dictionaries if you're checking for keys that you don't actually intend to use.
📋 Practical Task
The Social Media Hashtag Aggregator
You are building a tool to analyze trending topics. You have a list of posts, where each post is a string containing text and hashtags (words starting with #). Your goal is to create a mapping where every hashtag is a key, and the value is a set of unique usernames who used that hashtag.
Your Task:
- Import
defaultdictfromcollections. - Create a
defaultdictusing a factory that ensures the values are sets. - Process the following data:
posts = [ {"user": "alice", "text": "Loving the #python life! #coding"}, {"user": "bob", "text": "Just started learning #python. So cool!"}, {"user": "charlie", "text": "Check out this #coding tip! #python"}, {"user": "alice", "text": "Another #python post because I love it!"}, ] - Iterate through the posts, extract the hashtags, and add the user to the corresponding hashtag set.
- Print the final dictionary.
Hint: You can use post["text"].split() to get the words and a simple if word.startswith("#") to identify the hashtags.
There are no comments for now.