python - Combine dicts in a list if they have the same key -


i have dict looks this:

{'item1': [{'name1': 3}, {'name2': 4}, {'name1':7}],  'item2': [{'name7': 44}, {'name2': 3}, {'name6':9}, {'name6':2}] } 

i want combine dictionaries in list attached key such if there multiple dicts same key, can combine them (sum) , leave others are.

the output like:

{'item1': [{'name1': 10}, {'name2': 4}],  'item2': [{'name7': 44}, {'name2': 3}, {'name6': 11}] } 

i can't figure out how in python elegantly list/dict comprehension.

this uses collections.counter. elegant come with, because of convoluted structure of input - list of 1-length dictionaries indeed better implemented single dictionary, comments suggest. code transforms to, although have provided more possible tranformations if direly need old data structure. if do, recommend using tuples key-value pairs rather single-length dicts, seen in tuple_output. recommend use output or dict_output.

from collections import counter  d = {'item1': [{'name1': 3}, {'name2': 4}, {'name1':7}], 'item2': [{'name7': 44}, {'name2': 3}, {'name6':9}, {'name6':2}] }  output = {} k, v in d.items():     c = counter()     sub_dict in v:         c.update(sub_dict)     output[k] = c  dict_output = {k: dict(v) k, v in output.items()} tuple_output = {k: v.most_common() k, v in output.items()} dict_list_output = {k: [{a: b} a, b in v.most_common()] k, v in output.items()}  print(output) #{'item1': counter({'name1': 10, 'name2': 4}), 'item2': counter({'name7': 44, 'name6': 11, 'name2': 3})}  print(dict_output) #{'item1': {'name1': 10, 'name2': 4}, 'item2': {'name7': 44, 'name2': 3, 'name6': 11}}  print(tuple_output) #{'item1': [('name1', 10), ('name2', 4)], 'item2': [('name7', 44), ('name6', 11), ('name2', 3)]}  print(dict_list_output) #{'item1': [{'name1': 10}, {'name2': 4}], 'item2': [{'name7': 44}, {'name6': 11}, {'name2': 3}]} 

of course, if change starting data structure altogether, become lot easier manage. if use dictionary strings counters, can use counter interface update (refer link)

edit:

just fun, done in 1 line:

results = {item: reduce(lambda a, b: [a, a.update(b)][0], names, counter()) item, names in d.items()} 

it inspired yours, except builds 1 counter instance (given initial value reduce) per list. also, little bit of golfy trick required reduce properly, counter.update in place. if you're reading this, shouldn't use it, , instead build data structure counters or dicts start, mentioned earlier.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -