0

I'm trying to write a function that merges the items in multiple dictionaries under a single dictionary for matching keys.

For example, given

dict1 = {1:3, 2:4}
dict2 = {1:5, 2:6}

the function must return:

dict3 = {1:(3,5),2:(4,6)}

I also want the values to be numerically sorted, i.e. like this:

{1:(3,5)}

instead of this:

{1:(5,3)}

So far, I tried this, but it didn't work as I expected:

def mergeDicts(dict1, dict2):
   dict3 = {**dict1, **dict2}
   for key, value in dict3.items():
       if key in dict1 and key in dict2:
               dict3[key] = (value , dict1[key])

   return dict3
3
  • Do dict1 and dict2 have exactly the same keys? Commented May 9, 2020 at 13:20
  • yes same key different values
    – Herpes Qwe
    Commented May 9, 2020 at 13:21
  • 1
    {k: (d1[k], d2[k]) for k in d1}
    – erip
    Commented May 9, 2020 at 13:22

7 Answers 7

1

You may use a defaultdict and a list as type of value, then iterate both dict1 and dict2 and their value in the list pointed by the key

def mergeDicts(dict1, dict2):
    dict3 = defaultdict(list)
    for key, value in dict1.items():
        dict3[key].append(value)
    for key, value in dict2.items():
        dict3[key].append(value)
    return dict(dict3)

Generic method that can accept any amount of dict as parameters

def mergeDicts(*dicts):
    dict3 = defaultdict(list)
    for d in dicts:
        for key, value in d.items():
            dict3[key].append(value)
    return dict(dict3)

Achieving the same with dict-comprehension

def mergeDicts(dict1, dict2):
    return {k: [dict1[k], dict2[k]] for k in dict1}

def mergeDicts(*dicts):
    return {k: [d[k] for d in dicts] for k in dicts[0]}
1

You can do like this:

dict1 = {1:3, 2:4} 
dict2 = {1:5, 2:6}
ds = [dict1, dict2]
d = {}
for k in dict1.iterkeys():
    d[k] = tuple(d[k] for d in ds)
print(d)
1
  • Note: in Python 3 dict.iterkeys() are replaced with dict.keys(). Commented May 9, 2020 at 14:59
0

I believe this is closer to what you want than the other answer.

def mergeDicts(dict1, dict2):
    dict3 = {}
    for key, value in dict1.items():
        if key in dict2:
            dict3[key] = (value, dict2[key])
return dict3
0
0

You could do it lke this:

dict1 = {1:3, 2:4}
dict2 = {1:5, 2:6}

def mergeDicts(dict1, dict2):
    dict3 = {}
    for key, value in dict1.items():
        dict3[key] = (value, dict2[key])
    return dict3
0

Assume keys are going to be same in both dictionary

def mergeDicts(dict1, dict2):
   dict3 = {}
   for i in dict1.keys():
     dict3[i] = dict1[i], dict2[i]
   return dict3
0
0

Assuming the dicts might have fully/partially different keys:

def mergeDicts(d1:dict, d2:dict):
    keys=set(list(d1.keys())+list(d2.keys()))
    keys_inter=set(d1.keys()).intersection(d2.keys())
    d=dict()
    for k in keys:
        d[k]=[d1[k], d2[k]] if k in keys_inter else [(d1.get(k, None) or d2.get(k, None))]
    return d
0

The following provides exactly the output that you are seeking.

from collections import defaultdict
from itertools import chain 

dict1 = {1:3, 2:4} 
dict2 = {1:5, 2:6} 
dict3 = defaultdict(list)
for (k,v) in chain(dict1.items(), dict2.items()):
    dict3[k].append(v)
for k in dict3.keys():
    dict3[k] = tuple(dict3[k])

output

defaultdict(<class 'list'>, {1: (3, 5), 2: (4, 6)})

Not the answer you're looking for? Browse other questions tagged or ask your own question.