Chris Chris - 6 days ago 5
Python Question

Merge dictionaries into dictionary of lists

I have three dictionaries:

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'b': 3, 'c': 4}
dict3 = {'c': 4, 'd': 4}


I want to 'merge' them into a dictionary of lists

merged_dict = {'a':[1, np.nan, np.nan],
'b':[2, 3, np.nan],
'c':[3, 4, 4],
'd':[np.nan, np.nan, 4]}


There are keys that are in some dictionaries and not others which makes it kind of a pain to loop though. Wondering what the cleanest way to do this is.

Answer

As mentioned in the comments you need to iterate over all the dictionaries first to collect all the keys, otherwise there's no way of knowing what keys are missing from each individual dict. Then you can build merged_dict with a dict comprehension.

import numpy as np

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'b': 3, 'c': 4}
dict3 = {'c': 4, 'd': 4}

all_dicts = (dict1, dict2, dict3)

keys = {k for d in all_dicts for k in d}
merged_dict = {k: [d.get(k, np.nan) for d in all_dicts] for k in keys} 
print(merged_dict)   

output

{'a': [1, nan, nan], 'b': [2, 3, nan], 'c': [3, 4, 4], 'd': [nan, nan, 4]}

You could put the set comprehension inside the dict comprehension, but I think that makes the code harder to read.

merged_dict = {k: [d.get(k, np.nan) for d in all_dicts] 
    for k in {k for d in all_dicts for k in d}}

Actually, that double for loop in the set comp isn't so efficient. It probably doesn't matter much for small dicts, but if the dicts are large it'd be more efficient to do one of those loops at C speed using the set.update method:

keys = set()
for d in all_dicts:
    keys.update(d.keys())
Comments