Spero di non reinventare la ruota ma la soluzione è piuttosto breve. E, superfun da codificare.
def merge(source, destination):
"""
run me with nosetests --with-doctest file.py
>>> a = { 'first' : { 'all_rows' : { 'pass' : 'dog', 'number' : '1' } } }
>>> b = { 'first' : { 'all_rows' : { 'fail' : 'cat', 'number' : '5' } } }
>>> merge(b, a) == { 'first' : { 'all_rows' : { 'pass' : 'dog', 'fail' : 'cat', 'number' : '5' } } }
True
"""
for key, value in source.items():
if isinstance(value, dict):
# get node or create one
node = destination.setdefault(key, {})
merge(value, node)
else:
destination[key] = value
return destination
Quindi l'idea è quella di copiare il codice sorgente alla destinazione, e ogni volta che si tratta di un dict nella fonte, recurse. Quindi in effetti avrai un bug se in A un dato elemento contiene un dict e in B un altro tipo.
[EDIT] come detto nei commenti la soluzione era già qui: https://stackoverflow.com/a/7205107/34871
Dup http://stackoverflow.com/questions/7204805/python-dictionaries-of-dictionaries-merge – GLES