I wanted to merge nested dicts, but I can't find any suitable articles.
Make a dict for the time being.
dict1 = {
"depth1_a": "x1a",
"depth1_b": "x1b",
"depth2_1": {
"depth2_a" : "x2a",
"depth2_b" : "x2b"
},
"depth3_1": {
"depth3_2": {
"depth3_3_a" : "x33a",
"depth3_3_b" : "x33b"
}
}
}
dict2 = {
"depth1_a": "y1a",
"depth1_c": "y1c",
"depth2_1": {
"depth2_a" : "y2a",
"depth2_c" : "y2c"
},
"depth3_1": {
"depth3_2": {
"depth3_3_a" : "y33a",
"depth3_3_c" : "y33c"
}
}
}
The result is that "depthx_a" is overwritten with the value of dict2, and both "depthx_b" and "depthx_c" remain.
I tried several methods with reference to Various ways to merge multiple dictionaries, but "depthx_b" disappears after the second stage of nesting. ..
dict1.update(dict2)
print(dict1)
{
"depth1_a": "y1a",
"depth1_b": "x1b",
"depth2_1": {
"depth2_a": "y2a",
"depth2_c": "y2c"
},
"depth3_1": {
"depth3_2": {
"depth3_3_a": "y33a",
"depth3_3_c": "y33c"
}
},
"depth1_c": "y1c"
}
The depth1_a / depth1_b / depth1_c in the first stage of the nest was as expected, but other than that, it was overwritten with the key without going to see the contents.
From Python 3.3, there seems to be ChainMap, so I will try it.
from collections import ChainMap
dict_map = ChainMap(dict1, dict2)
dict(dict_map)
{
"depth1_a": "y1a",
"depth1_c": "y1c",
"depth2_1": {
"depth2_a": "y2a",
"depth2_c": "y2c"
},
"depth3_1": {
"depth3_2": {
"depth3_3_a": "y33a",
"depth3_3_c": "y33c"
}
},
"depth1_b": "x1b"
}
No.
After all, when I was wandering around I have to do it myself, it's annoying, etc. [dictknife.deepmerge](https://pypi.org/ I found something like project / dictknife / 0.4.0 /). I have no choice but to expect from the name.
from dictknife import deepmerge
deepmerge(dict1, dict2)
{
"depth1_a": "y1a",
"depth1_b": "x1b",
"depth2_1": {
"depth2_a": "y2a",
"depth2_b": "x2b",
"depth2_c": "y2c"
},
"depth3_1": {
"depth3_2": {
"depth3_3_a": "y33a",
"depth3_3_b": "x33b",
"depth3_3_c": "y33c"
}
},
"depth1_c": "y1c"
}
This is what I was looking for!
However, unfortunately, the behavior when inserting different types is subtle.
If I put None in the literal value like " depth3_3_a ": None
, it will be overwritten and become None, but if I wanted to delete the nest branch itself and set "depth3_2": None
, it was simply ignored.
In that case, I got an error when I set " depth3_2 ":" "
.
Sorry.
However, this deep merge, Japanese information does not come out so much that I am surprised at all. It's convenient, so I think everyone should use it.
Recommended Posts