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:
- merge the dictionaries by appending the lists
- 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,[])] }