Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでネストされた辞書をフラットな辞書に変換する方法

非構造化データが世界中で活用されるようになった今、ネストされたJSONのようにデータ構造が深く入れ子になっている形式に遭遇することは珍しくありません。Pythonでは、内側のキーと外側のキーを連結することで、ネストされたデータ構造をフラット化(平坦化)して扱うことができます。

この記事では、ネストされた辞書(dict)を受け取り、それをフラットな辞書へ変換する2つの方法を紹介します。

方法1:再帰処理を使ったアプローチ

まずは、自分で関数を実装する再帰的なアプローチです。この方法では、辞書内の各要素を再帰的に処理する関数を設計します。引数として、処理対象の辞書、出力用の辞書(プレースホルダー)、親キー、区切り文字を受け取ります。isinstanceを使って次の要素がそれ自身辞書かどうかを判定し、辞書であれば再帰呼び出しに渡してさらに掘り下げていきます。

サンプルコード

dictA = {
    "id": "0001",
    "name": "hotdog",
    "image":
        {
            "url": "images/0001.jpg",

            "thumbnail":
                {
                    "url": "images/thumbnails/0001.jpg",
                    "height,width": "2x4"
                }
        }
}
def dict_flatten(in_dict, dict_out=None, parent_key=None, separator="_"):
    if dict_out is None:
        dict_out = {}

    for k, v in in_dict.items():
        k = f"{parent_key}{separator}{k}" if parent_key else k
        if isinstance(v, dict):
            dict_flatten(in_dict=v, dict_out=dict_out, parent_key=k)
            continue

        dict_out[k] = v

    return dict_out

final_dict = dict_flatten(dictA)
print(final_dict)

実行結果

上記のコードを実行すると、以下のような結果が得られます。

{
    'id': '0001',
    'name': 'hotdog',
    'image_url': 'images/0001.jpg',
    'image_thumbnail_url': 'images/thumbnails/0001.jpg',
    'image_thumbnail_height,width': '2x4'
}

ご覧のとおり、「image」→「thumbnail」→「url」という深い階層のキーが、image_thumbnail_urlのようにアンダースコア(_)で連結された単一のキーに変換され、完全にフラットな辞書になっています。区切り文字はseparator引数で自由に変更できます。

方法2:cherrypickerライブラリを使う

手軽に済ませたい場合は、cherrypickerというライブラリを利用する方法もあります。このモジュールは、辞書を入力として直接渡すだけでフラット化でき、デフォルトの区切り文字はハイフン(-)です。

サンプルコード

from cherrypicker import CherryPicker

dictA = {
    "id": "0001",
    "name": "hotdog",
    "image":
        {
            "url": "images/0001.jpg",

            "thumbnail":
                {
                    "url": "images/thumbnails/0001.jpg",
                    "height,width": "2x4"
                }
        }
}

picker = CherryPicker(dictA)
print(picker.flatten().get())

実行結果

上記のコードを実行すると、以下のような結果が得られます。

{
    'id': '0001',
    'name': 'hotdog',
    'image_url': 'images/0001.jpg',
    'image_thumbnail_url': 'images/thumbnails/0001.jpg',
    'image_thumbnail_height,
    width': '2x4'
}

まとめ

ネストされた辞書のフラット化には、大きく分けて2つの選択肢があります。

  • 再帰関数を自作する方法: 外部ライブラリに依存せず、区切り文字やキーの連結ルールを細かくカスタマイズできるのがメリットです。
  • cherrypickerを使う方法: 数行のコードで実装でき、手軽さが魅力です。ただし別途インストールが必要です。

APIレスポンスや設定ファイルなど、深くネストしたJSONデータを扱う際には、用途やプロジェクトの要件に応じて最適な方法を選びましょう。

  1. 【初心者向け】Pythonの辞書(dict)をリストに変換する3つの方法

    Pythonの辞書をリストに変換するには? Pythonの辞書(dict)クラスには、リストへの変換に便利なメソッドが3つ用意されています。それぞれitems()、keys()、values()で、以下のようなビューオブジェクトを返します。 items():キーと値のペア(タプル)で構成されるビューオブジェクト keys():キーのみで構成されるビューオブジェクト values():値のみで構成されるビューオブジェクト これらのビューオブジェクトは、組み込み関数 list() を使うことで、簡単にリストオブジェクトへ変換できます。 実際のコード例 以下は、辞書から各ビューオブジェクトを取

  2. Pythonで文字列を辞書(dict)に変換する方法|ast.literal_evalとjson.loadsの使い分け

    Pythonでは、文字列形式で表現された辞書データを実際のdictオブジェクトに変換したい場面がよくあります。主な方法としては、標準ライブラリの ast.literal_eval() を使う方法と、json モジュールを使う方法の2つがあります。それぞれの特徴と使い方を詳しく見ていきましょう。 方法1:ast.literal_eval() を使う ast.literal_eval() は、文字列をPythonの式として安全に評価する関数です。任意のコードを実行できてしまう eval() とは異なり、リテラル構造以外は評価しないため、セキュリティ面でも安心して利用できます。 評価できるのは、文