Home > Net >  Merge a two dictionaries based on keys with no duplicates
Merge a two dictionaries based on keys with no duplicates

Time:10-17

Dict 1 :

{'result2': [{'2': '22'}, {'22': '222'}], 'result1': [{'1': '11'}, {'11': '111'}]}

Dict 2:

{'result2': [{'two': 'twentytwo'}, {'22': '222'}], 'result1': [{'one': 'eleven'}, {'11': '111'}]}

I want to merge them based on keys result1 and result 2 and preserve the same format.

Expected Output

{"result1":[{"1":"11"},{"one":"eleven"},{"11":"111"}]},{"result2":[{"2":"22"},{"two":"twentytwo"},{"22":"222"}]}

And the keys of both dict may not necessarily have same index.

CodePudding user response:

It's always good to add desired format for output. It likes you want to list of dict which contains data from both with respect to result1 & result 2.

Given -

a = [{"result1":[{"1":"11"},{"11":"111"}]},{"result2":[{"2":"22"},{"22":"222"}]}]
b = [{"result1":[{"one":"eleven"},{"11":"111"}]},{"result2":[{"two":"twentytwo"},{"22":"222"}]}]

Here is code-

desired_op = []
for index, item in enumerate(a):
   inner_item = {}
   for key, value in item.items():
     #print (key, value   b[index][key])
     inner_item[key] = value   b[index][key]
   desired_op.append(inner_item)
 
print (desired_op)
[{'result1': [{'1': '11'}, {'11': '111'}, {'one': 'eleven'}, {'11': '111'}]}, {'result2': [{'2': '22'}, {'22': '222'}, {'two': 'twentytwo'}, {'22': '222'}]}]

If you need unique items, it will be bit complex-

desired_op = []
 for index, item in enumerate(a):
   inner_item = {}
   for key, value in item.items():
     #print (key, value   b[index][key])
     inner_item[key] = list({list(litem.keys())[0]:litem for litem in value   b[index][key]}.values())
   desired_op.append(inner_item)
 
print (desired_op)
[{'result1': [{'1': '11'}, {'11': '111'}, {'one': 'eleven'}]}, {'result2': [{'2': '22'}, {'22': '222'}, {'two': 'twentytwo'}]}]

follow up on comment

simple append can work, but for this you must be sure that first index from second list should contain result1 & second index should contain result2 as dict keys.

ex. (but this won't remove duplicates)

a[0]['result1'].extend(b[0]['result1'])
a[1]['result2'].extend(b[1]['result2'])
print(a)
[{'result1': [{'1': '11'}, {'11': '111'}, {'one': 'eleven'}, {'11': '111'}]}, {'result2': [{'2': '22'}, {'22': '222'}, {'two': 'twentytwo'}, {'22': '222'}]}]

if you aren't sure about index position in second list, this will work-

keys_mapping =  {list(item.keys())[0]:index for index, item in enumerate(a)}
print (keys_mapping)
{'result1': 0, 'result2': 1}

for item in b:
  key = list(item.keys())[0]
  a[keys_mapping[key]][key].extend(item[key])
print (a)
[{'result1': [{'1': '11'}, {'11': '111'}, [{'one': 'eleven'}, {'11': '111'}]]}, {'result2': [{'2': '22'}, {'22': '222'}, [{'two': 'twentytwo'}, {'22': '222'}]]}]

CodePudding user response:

You could separate this in two phases:

  1. merge the dictionaries by appending the lists
  2. remove duplicates from the resulting merged dictionary

...

dict1={'result2': [{'2': '22'}, {'22': '222'}], 
       'result1': [{'1': '11'}, {'11': '111'}]}
dict2={'result2': [{'two': 'twentytwo'}, {'22': '222'}], 
       'result1': [{'one': 'eleven'}, {'11': '111'}]}

# merge phase
dict3 = {k:dict1.get(k,[]) dict2.get(k,[]) for k in {*dict1,*dict2}}
        
# uniqueness phase
dict3 = {k:[d for i,d in enumerate(v) if v.index(d)==i] 
         for k,v in dict3.items()}
    
print(dict3)

{'result2': [{'2': '22'}, {'22': '222'}, {'two': 'twentytwo'}],
 'result1': [{'1': '11'}, {'11': '111'}, {'one': 'eleven'}]}

If dict1 and dict2 are guaranteed to have the same keys, then the merge phase can be performed more concisely:

dict3 = {k:v dict2[k] for k,v in dict1.items()}

Note that you could combine the two phases in one large dictionary comprehension:

dict3 = {k: [d for i,d in enumerate(v) if v.index(d)==i]
         for k in {*dict1,*dict2}
         for v in [dict1.get(k,[]) dict2.get(k,[])] }
  • Related