Reputation: 63
I am trying to merge two dict
s in Python that could be The same or one could have far less info
ex.
master = {"a": 5564, "c": [{"d2":6}]}
daily = { "a": 795, "b": 1337, "c": [{"d1": 2,"d2": 2,"d3": [{"e1": 4,"e2": 4}]}]}
They need to be merged so the output is as such
master = { "a": 6359, "b": 1337, "c": [{"d1": 2,"d2": 8,"d3": [{"e1": 4,"e2": 4}]}]}
I took a shot at it though I only ever get returned null. I might be missing something or just way off. I just cant figure it out. Any help would be amazing Thank you.
def merge(master,daily):
for k, v in daily.items():
if isinstance(daily[k],list):
key_check = keyCheck(k, master)
if key_check:
merge(master[k],daily[k])
else :
master[k] = daily[k]
else :
if keyCheck(k, master):
master[k] += daily[k]
else :
master[k] = daily[k]
keyCheck
only checks if a key is in the dictionary so it doesn't throw errors.
Upvotes: 3
Views: 87
Reputation: 4510
Here is a recursive solution. Though it cannot compete with Kasramvd's answer.
def merge(dic1, dic2):
merged = dict(dic1, **dic2) # Merge dictionaries without adding values. Just exchanging them.
# Similar to .update() but does not override subdicts.
for key in merged:
if key in dic1 and key in dic2:
if isinstance(dic1[key], list):
merged[key] = merge(dic1[key][0], dic2[key][0])
else:
merged[key] = dic1[key] + dic2[key]
return merged
Upvotes: 1
Reputation: 107287
Here is a one linear using collections.Counter()
:
>>> from collections import Counter
>> C2 = Counter(daily)
>>> C1 = Counter(master)
>>>
>>> {k:reduce(lambda x,y : Counter(x)+Counter(y), v) if isinstance(v, list) and k in (C1.viewkeys() & C2) else v for k, v in (C1 + C2).items()}
{'a': 6359, 'c': Counter({'d3': [{'e1': 4, 'e2': 4}], 'd2': 8, 'd1': 2}), 'b': 1337}
First off, you can convert your dictionaries to Counter objects in order to add the values for common keys after summing the counters (that's how Counter's add attribute works), then you can loop over the items and for keys that exist in both counters and their values are lists, you can use the reduce()
function to apply the same algorithm to all of the list items too.
If your list contains another nested similar data structure, you can convert this code to a recursive function.
Upvotes: 5