@FM's answer has the right general idea, i.e. a recursive solution, but somewhat peculiar coding and at least one bug. I'd recommend, instead:
Python 2:
import collections
def update(d, u):
for k, v in u.iteritems():
if isinstance(v, collections.Mapping):
d[k] = update(d.get(k, {}), v)
else:
d[k] = v
return d
Python 3:
import collections.abc
def update(d, u):
for k, v in u.items():
if isinstance(v, collections.abc.Mapping):
d[k] = update(d.get(k, {}), v)
else:
d[k] = v
return d
The bug shows up when the "update" has a k
, v
item where v
is a dict
and k
is not originally a key in the dictionary being updated -- @FM's code "skips" this part of the update (because it performs it on an empty new dict
which isn't saved or returned anywhere, just lost when the recursive call returns).
My other changes are minor: there is no reason for the if
/else
construct when .get
does the same job faster and cleaner, and isinstance
is best applied to abstract base classes (not concrete ones) for generality.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…