Quantcast
Channel: rana_kualuの記事 - Qiita
Viewing all articles
Browse latest Browse all 339

Pythonでネストしたdictをマージしたい

$
0
0

ネストしたdictをマージしたかったのだけど、適切な記事が全く見当たらない。

とりあえずdictをつくる。

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"}}}

結果として欲しいのは、"depthx_a"はdict2の値で上書きされる、"depthx_b"と"depthx_c"は両方とも残る、というものです。

複数の辞書のマージ方法いろいろなどを参考に幾つか試してみたのですが、ネストの二段階目以降で"depthx_b"が消えます。

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"}

ネストの一段階目にあるdepth1_a/depth1_b/depth1_cは想定通りになりましたが、それ以外は中身を見に行かずにキーで上書きされてしまいました。

Python3.3からはChainMapというのがあるらしいので試してみます。

fromcollectionsimportChainMapdict_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"}

はいだめー。

結局最終的に自力でやるしかないのかよ、めんどくさいなあ、などと彷徨ってたらdictknife.deepmergeとかいうのを見つけました。
名前からして期待しかない。

fromdictknifeimportdeepmergedeepmerge(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"}

これだよ俺の求めていたものは!

ただ残念ながら異なる型を突っ込んだ時の挙動が微妙です。
"depth3_3_a": Noneみたいにリテラル値にNoneを突っ込んだら上書きされてNoneになるのですが、ネストの枝そのものを削除したくて"depth3_2": Noneとしたら単に無視されました。
それならばと"depth3_2": ""にしたらエラーになりました。
残念。

しかしこのdeepmerge、日本語情報が全くさっぱりびっくりするほど出てこないな。
便利なのでみんなも使うといいと思います。


Viewing all articles
Browse latest Browse all 339

Trending Articles