Prashant
Prashant

Reputation: 402

Merge nested dictionaries with common / overlapping keys

I have two dictionaries, I want to merge following two dictionary into one.

How can I merge them efficiently?

Dict1

{
    UUID('id1'): {
        'due': datetime.date(2018, 3, 10),
        'status': 'Done',
    }, UUID('id2'): {
        'due_date': datetime.date(2018, 3, 10),
        'old_status': 'Done',
    }
}

Dict2

{
    UUID('id1'): {
        'new_val': 'Pass',
        'amount': 123.0,
    }, UUID('id2'): {
        'new_val': 'Fail',
        'amount': 0,
    }
}

Desired Output

{
    UUID('id1'): {
        'due': datetime.date(2018, 3, 10),
        'status': 'Done',
        'new_val': 'Pass',
        'amount': 123.0,
    }, UUID('id2'): {
        'due_date': datetime.date(2018, 3, 10),
        'old_status': 'Done',
        'new_val': 'Fail',
        'amount': 0,
    }
}

Upvotes: 0

Views: 1387

Answers (3)

jpp
jpp

Reputation: 164653

You can use ** unpacking notation together with dict.get default parameter of {} to combine your dictionaries.

This will handle cases where keys in one dictionary are not in the other, and allow us to iterate the union of all keys.

keys = d1.keys() | d2.keys()

res = {k: {**d1.get(k, {}), **d2.get(k, {})} for k in keys}

Result

{'id1': {'amount': 123.0,
  'due': datetime.date(2018, 3, 10),
  'new_val': 'Pass',
  'status': 'Done'},
 'id2': {'amount': 0,
  'due_date': datetime.date(2018, 3, 10),
  'new_val': 'Fail',
  'old_status': 'Done'}}

Setup

import datetime

d1 = {
    'id1': {
        'due': datetime.date(2018, 3, 10),
        'status': 'Done',
    }, 'id2': {
        'due_date': datetime.date(2018, 3, 10),
        'old_status': 'Done',
    }
}

d2 = {
    'id1': {
        'new_val': 'Pass',
        'amount': 123.0,
    }, 'id2': {
        'new_val': 'Fail',
        'amount': 0,
    }
}

Upvotes: 1

Jay Shankar Gupta
Jay Shankar Gupta

Reputation: 6088

dict1={
    'UUID(id1)': {
        'due': 'datetime.date(2018, 3, 10)',
        'status': 'Done'
    }, 'UUID(id2)': {
        'due_date': 'datetime.date(2018, 3, 10)',
        'old_status': 'Done'
    }
}
dict2={'UUID(id1)':{
        'new_val': 'Pass',
        'amount': 123.0

}, 
        'UUID(id2)': {
        'new_val': 'Fail',
        'amount': 0
    }
}
finaldict = {key:(dict1[key], dict2[key]) for key in dict1}
print(finaldict)

output

{
'UUID(id1)': ({'due': 'datetime.date(2018, 3, 10)', 'status': 'Done'}, 
               {'new_val': 'Pass', 'amount': 123.0}), 
'UUID(id2)': ({'due_date': 'datetime.date(2018, 3, 10)', 'old_status': 'Done'}, 
              {'new_val': 'Fail', 'amount': 0})
}

Upvotes: 0

Samuel Muiruri
Samuel Muiruri

Reputation: 522

For dictionaries x and y, z becomes a merged dictionary with values from y replacing those from x.

In Python 3.5 or greater, :

z = {**x, **y}

In Python 2, (or 3.4 or lower) write a function:

def merge_two_dicts(x, y):
     z = x.copy()   # start with x's keys and values
     z.update(y)    # modifies z with y's keys and values & returns None
     return z

and

z = merge_two_dicts(x, y)

Upvotes: 0

Related Questions