LoginSignup
1
1

More than 1 year has passed since last update.

[python] Key-Value 形式の dict を階層構造の dict に

Posted at

やりたいこと

記事タイトルはちょっとわかりづらいというか不正確な気がしますが、やりたいことはコレ。

# ↓これを
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"
    }
  }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1