I have the following dict:
aDict = {
"a" : {
"b" : {
"c1" : {},
"c2" : {},
}
}
}
a second dict:
aSecondDict = {
"d1" : {},
"d2" : {},
"d3" : {},
}
and a "path" tuple:
path = ( "a", "b", "c2" )
I now want to add the second dict to the first at the path provided by the tuple:
aResultDict = {
"a" : {
"b" : {
"c1" : {},
"c2" : {
"d1" : {},
"d2" : {},
"d3" : {},
},
}
}
}
What is the pythonic way of achieving this?
You can use reduce
1 to get the dictionary and dict.update
to put the new stuff in there:
reduce(lambda d,key: d[key],path,aDict).update(aSecondDict)
You can even get a little more clever if you want:
reduce(dict.__getitem__,path,aDict).update(aSecondDict)
I suppose it should be noted that the two approaches are slightly different. The latter forces aDict
to only contain more dictionaries (or dict
subclasses) whereas the former allows for anything which has a __getitem__
method to be in aDict
. As noted in the comments, you could also use:
reduce(dict.get,path,aDict).update(aSecondDict)
However, this version will raise an AttributeError
if you try to traverse a "link" in the path which is non-existent rather than a KeyError
so I don't like it quite as much. This method also enforces that every value along the path is a dict
or dict
subclass.
1reduce
is a builtin for python2.x. Starting at python2.6 it is also available as functools.reduce
. Code which wants to be compatible with python3.x should try to use functools.reduce
as the builtin is removed in python3.x