やりたいこと
記事タイトルはちょっとわかりづらいというか不正確な気がしますが、やりたいことはコレ。
# ↓これを
src = {
"aaa": "A",
"bbb.ccc": "BC",
"bbb.ddd": "BD",
}
# ↓こうしたい
{
"aaa": "A",
"bbb": {
"ccc": "BC",
"ddd": "BD"
}
}
コードスニペット
とりあえず下記の function で実現できた。
もっとキレイに書けそうな気がするし、探せばライブラリもありそうだけど。
def kv_to_stare(kv, path_delimiter=".", base_path=""):
result = {}
for k, v in kv.items():
if len(base_path) > 0 and not k.startswith(f"{base_path}{path_delimiter}"):
continue
base_path_len = len(base_path)
path = k[base_path_len:].strip(path_delimiter)
paths = path.split(path_delimiter)
current_path = paths[0]
if len(paths) == 1:
result[current_path] = v
else:
next_base_path = f"{base_path}.{current_path}".strip(path_delimiter)
result[current_path] = kv_to_stare(kv, path_delimiter, next_base_path)
return result
使用例
import json
# Inputデータ
src = {
"aaaa": "AAA",
"bbbb": "BBB",
"cccc.dddd": "CCCDDD",
"cccc.eeee": "CCCEEE",
"ffff.gggg.gggg": "FGG",
"ffff.gggg.hhhh": "FGH",
"ffff.iii.aaa": "FIA",
"cccc.kkkk": "CCCKKK",
}
# 実行&表示
result = kv_to_stare(src)
print(json.dumps(result, indent=2))
### ▼結果 ###
{
"aaaa": "AAA",
"bbbb": "BBB",
"cccc": {
"dddd": "CCCDDD",
"eeee": "CCCEEE",
"kkkk": "CCCKKK"
},
"ffff": {
"gggg": {
"gggg": "FGG",
"hhhh": "FGH"
},
"iii": {
"aaa": "FIA"
}
}
}