Combine values of same keys in a list of dicts
bar = {
k: [d.get(k) for d in foo]
for k in set().union(*foo)
}
Things to google:
- python list comprehension
- python dict comprehension
- python star
- python dict get
- python set union
I am just going to complement Alex Hall solution here, so that it does not return a lot of "None" values:
def merge_dictionary_list(dict_list):
return {
k: [d.get(k) for d in dict_list if k in d] # explanation A
for k in set().union(*dict_list) # explanation B
}
Explanation:
- The whole thing inside
{}
is a dictionary comprehension - Explanation A: Go through all elements in dictionary list and get values for current key
k
if the current dictionary (d
) being evaluated actually has that key.
OBS: Without the if k in d
expression there could be a bunch of None
values appended to the arrays in case the list of dictionaries
contains different types of keys.
- Explanation B: gets all keys from list of dictionary and unite them distinctly by using
set().union
. After all we can only have distinct elements in set data structure.
If you want to do it the traditional way, just go with:
def merge_list_of_dictionaries(dict_list):
new_dict = {}
for d in dict_list:
for d_key in d:
if d_key not in new_dict:
new_dict[d_key] = []
new_dict[d_key].append(d[d_key])
return new_dict
I think the first solution looks more elegant, but the second one is more legible/readable.
Kind Regards :)
I would do this in two steps:
Collect all keys into a single iterable:
>>> import operator >>> from functools import reduce >>> all_keys = reduce(operator.or_, (d.keys() for d in foo)) >>> all_keys {'a', 'b', 'c'}
Use a dict comprehension to create the desired result:
>>> bar = {key: [d.get(key) for d in foo] for key in all_keys} >>> bar {'a': ['x', 'j'], 'b': ['y', None], 'c': ['z', 'z']}