Aggregating multiple dictionaries is a frequent task in Python, whether you are merging configuration files, combining datasets, or summing up counters. Depending on your goal, "aggregation" might mean a simple merge (overwriting duplicates) or a complex combination (summing values or recursive merging).
This guide covers the most efficient techniques to aggregate dictionaries, ranging from standard merging operators to deep recursive updates.
Standard Merging (Last Value Wins)
If your goal is to combine dictionaries where keys from later dictionaries overwrite earlier ones, Python provides several built-in methods.
The Merge Operator | (Python 3.9+)
The cleanest syntax for merging dictionaries is the union operator |.
default_settings = {"theme": "light", "notifications": True}
user_settings = {"theme": "dark"}
config = default_settings | user_settings
print(f"Merged Config: {config}")Output:
Merged Config: {'theme': 'dark', 'notifications': True}Unpacking ** (Python 3.5+)
For older Python versions, dictionary unpacking is the standard approach.
dict_a = {"a": 1, "b": 2}
dict_b = {"b": 3, "c": 4}
merged = {**dict_a, **dict_b}
print(f"Merged: {merged}")Output:
Merged: {'a': 1, 'b': 3, 'c': 4}Aggregating Values (Summing Duplicates)
A common issue with standard merging is that it replaces values. If you want to aggregate values (e.g., sum up scores or inventory counts) for shared keys, you need a different approach.
Using collections.Counter
The Counter class is the most efficient tool for summing integer values across dictionaries.
from collections import Counter
sales_q1 = {"apples": 100, "bananas": 50}
sales_q2 = {"apples": 200, "oranges": 30}
total_sales = Counter(sales_q1) + Counter(sales_q2)
print(f"Total Sales: {dict(total_sales)}")Output:
Total Sales: {'apples': 300, 'bananas': 50, 'oranges': 30}Using Dictionary Comprehension (Custom Logic)
If you need non-numeric aggregation (like concatenating lists or strings), use a set of all keys and a comprehension.
d1 = {"team": "Alpha", "tags": ["red"]}
d2 = {"team": "Beta", "tags": ["blue"]}
all_keys = set(d1) | set(d2)
aggregated = {
k: d1.get(k, []) + d2.get(k, [])
for k in all_keys
if k == "tags" # Logic specific to 'tags'
}
print(aggregated)Output:
{'tags': ['red', 'blue']}Deep Merging (Recursive Aggregation)
When working with nested dictionaries (like JSON configurations), a shallow merge (| or update) will completely replace nested dictionaries rather than merging their contents. You need a recursive function.
def deep_merge(dict1, dict2):
"""
Recursively merges dict2 into dict1.
"""
result = dict1.copy()
for key, value in dict2.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
result[key] = deep_merge(result[key], value)
else:
result[key] = value
return result
config_base = {
"server": {
"host": "localhost",
"port": 8080
}
}
config_override = {
"server": {
"port": 9000 # Only override port, keep host
}
}
full_config = deep_merge(config_base, config_override)
print(f"Deep Merged: {full_config}")Output:
Deep Merged: {'server': {'host': 'localhost', 'port': 9000}}Aggregating a List of Dictionaries
Often data comes as a list of dictionaries, and you need to combine them all into a single result.
Using functools.reduce
reduce applies a function cumulatively to items in a sequence.
from functools import reduce
data = [
{"a": 1, "b": 2},
{"b": 3, "c": 4},
{"d": 5}
]
def merge_logic(acc, curr):
return {**acc, **curr} # Simple merge (last wins)
final_dict = reduce(merge_logic, data)
print(f"Reduced Dict: {final_dict}")Output:
Reduced Dict: {'a': 1, 'b': 3, 'c': 4, 'd': 5}Conclusion
To aggregate dictionaries effectively in Python:
- Use
|(Python 3.9+) or**unpacking for simple merging where the last value overwrites previous ones. - Use
collections.Counterif you need to perform arithmetic aggregation (summing numbers) on shared keys. - Use a recursive function if you need to merge nested structures (deep merge) without losing data in sub-dictionaries.