I want to merge nested dicts in Python

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

I want to merge nested dicts in Python
I want to do Dunnett's test in Python
I want to create a window in Python
I want to display the progress in Python!
I want to write in Python! (1) Code format check
I want to easily implement a timeout in python
[Python] I want to merge Excel files anyway (pandas.merge)
I want to write in Python! (2) Let's write a test
Even in JavaScript, I want to see Python `range ()`!
I want to randomly sample a file in Python
I want to work with a robot in python.
[Python] I want to make a nested list a tuple
I want to write in Python! (3) Utilize the mock
I want to use the R dataset in python
I want to do something in Python when I finish
I want to manipulate strings in Kotlin like Python!
I want to debug with Python
I want to do something like sort uniq in Python
I want to be able to run Python in VS Code
I want to make input () a nice complement in python
I tried to implement PLSA in Python
I tried to implement permutation in Python
I want to print in a comprehension
I want to use jar from python
I want to build a Python environment
I want to analyze logs with Python
I want to play with aws with python
I tried to implement ADALINE in Python
I wanted to solve ABC159 in Python
I tried to implement PPO in Python
I want to embed Matplotlib in PySimpleGUI
I want to solve APG4b with Python (only 4.01 and 4.04 in Chapter 4)
[Python / AWS Lambda layers] I want to reuse only module in AWS Lambda Layers
I want to use MATLAB feval with python
I want to pin Datetime.now in Django tests
I want to memoize including Python keyword arguments
I was able to recurse in Python: lambda
I want to email from Gmail using Python.
[Python] I want to manage 7DaysToDie from Discord! 1/3
I want to make a game with Python
I wrote "Introduction to Effect Verification" in Python
I want to convert a table converted to PDF in Python back to CSV
I want to batch convert the result of "string" .split () in Python
I want to explain the abstract class (ABCmeta) of Python in detail.
I tried to implement TOPIC MODEL in Python
I want to use Temporary Directory with Python2
Environment maintenance made with Docker (I want to post-process GrADS in Python
I want to color a part of an Excel string in Python
I want to use ceres solver from python
#Unresolved I want to compile gobject-introspection with Python3
I want to solve APG4b with Python (Chapter 2)
I want to sell Mercari by scraping python
[Python] I want to manage 7DaysToDie from Discord! 2/3
I want to make C ++ code from Python code!
I tried to implement selection sort in python
I want to write to a file with Python
I want to do a monkey patch only partially safely in Python
I tried to implement merge sort in Python with as few lines as possible
[Python] I want to know the variables in the function when an error occurs!
I want to use Python in the environment of pyenv + pipenv on Windows 10
I want to create a priority queue that can be updated in Python (2.7)