How to Group Data in Python with defaultdict and Comprehensions
Group a list of items by a computed key using a defaultdict-based generator helper and an alternative dictionary comprehension approach.
Python code
31 linesfrom collections import defaultdict
def group_by(data, key_func):
"""Group items in data by the value returned by key_func."""
result = defaultdict(list)
for item in data:
result[key_func(item)].append(item)
return dict(result)
def group_by_comprehension(data, key_func):
"""Same grouping using a dictionary comprehension with a set of unique keys."""
return {key: [item for item in data if key_func(item) == key]
for key in {key_func(item) for item in data}}
if __name__ == "__main__":
people = [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 30},
{"name": "Diana", "age": 25},
]
by_age = group_by(people, lambda p: p["age"])
print("Using generator-based helper:")
for age, group in sorted(by_age.items()):
print(f" Age {age}: {[p['name'] for p in group]}")
by_age_comp = group_by_comprehension(people, lambda p: p["age"])
print("Using comprehension-based helper:")
for age, group in sorted(by_age_comp.items()):
print(f" Age {age}: {[p['name'] for p in group]}")
Output
Using generator-based helper:
Age 25: ['Bob', 'Diana']
Age 30: ['Alice', 'Charlie']
Using comprehension-based helper:
Age 25: ['Bob', 'Diana']
Age 30: ['Alice', 'Charlie']
How it works
The group_by function uses defaultdict(list) to avoid checking if a key already exists; appending to a missing key automatically creates an empty list. The comprehension-based variant first builds a set of unique keys with a set comprehension, then uses a dictionary comprehension that scans the data once per key — simpler to read but O(n²) for large datasets. Both produce identical grouping, demonstrating two idioms for the same task: the procedural loop is efficient and clear, while the comprehension is compact and functional. For production code with large inputs, prefer the defaultdict approach for linear time.
Common mistakes
- Forgetting to convert defaultdict back to a normal dict with dict() when you need a plain dictionary.
- Using a list comprehension repeatedly inside a dict comprehension causes O(n²) time on large data.
- Assuming the key function returns hashable values; if not, grouping will fail.
- Not sorting keys before printing, which makes output order unpredictable.
Variations
- Use itertools.groupby after sorting data by the key for memory-efficient grouping of consecutive runs.
- Use pandas groupby() to group DataFrame rows by a column when working with tabular data.
Real-world use cases
- Grouping API response records by user ID before rendering a dashboard.
- Batching log entries by error code to aggregate error counts per service.
- Partitioning inventory items by category to generate per-category reports.
Sponsored
More from Comprehensions & generators
- Batch Rows in Chunks with a Generator in Python easy
- Build a Generator Pipeline in Python: Filter Then Map medium
- Build a lazy generator to read file lines in Python easy
- Chunk an Iterable into Batches with a Generator in Python easy
- Convert Data in Python with Comprehensions and Generators easy
- Count Data in Python with Comprehensions and Generators easy
Keep learning
Related tutorials and quizzes for this topic.