I have a list of dictionaries in the following format:
foo = [
{'a': 'x', 'b': 'y', 'c': 'z'},
{'a': 'j', 'c': 'z'}
]
I want to group this list of dictionaries into a single dictionary, like:
bar = {
'a': ['x', 'j'],
'b': ['y', None],
'c': ['z', 'z']
}
What I've currently done is, looping through all the dicts in foo
and create a list of keys and then looping again over the same to create bar
. I wonder whether there is a simpler way to accomplish this. Can anyone help?
bar = {
k: [d.get(k) for d in foo]
for k in set().union(*foo)
}
Things to google:
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:
{}
is a dictionary comprehension 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.
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']}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.