i-focus i-focus BB
    • カテゴリ
    • 最近
    • タグ
    • 人気
    • ユーザー
    • グループ
    • 登録
    • ログイン

    深いネストを持った辞書型から安全かつ簡潔に値を取り出したいので調べた

    Python
    python
    2
    2
    412
    もっと見る
    • 古いものから新しい順
    • 新しいものから古い順
    • 最高評価
    返信
    • スレッドとして返信する
    投稿するのにログインして下さい
    このスレッドが削除されました。スレッド管理権を持っているユーザーにしか読めません。
    • i_yamasakiI
      i_yamasaki
      最後に編集した時間i_yamasaki

      結論

      jmespathライブラリを使うと良い

      やりたいこと

      今まで深いネストをした辞書から値を取り出す際には

      d = {"hoge": {"fuga": {"piyo": 1}}}
      
      v = d.get("hoge", {}).get("fuga", {}).get("piyo")
      # v = 1
      

      としていたが、非常に長ったらしいのでやめたかった。
      ネストをピリオドでつないで取得できるのが理想。

      調べたところ、ライブラリでの解決策としては「辞書型を拡張したクラスを使う」パターンと、「関数を通して辞書から指定の値を取り出す」パターンがあるらしい。

      「辞書型を拡張したサブクラスを使う」パターン

      pip install python-box
      
      from box import Box
      
      d = {"hoge": {"fuga": {"piyo": 1}}}
      
      mybox = Box(d, box_dots=True, default_box=True)
      v = mybox["hoge.fuga.piyo"]
      # v = <Box: 1>
      

      default_box=Trueでパスが存在しないときにも空のBoxオブジェクトが帰ってくる。
      想像していたものに近いがサブクラスの宣言がいちいち必要なのが面倒。

      「関数を通して辞書から指定の値を取り出す」パターン

      pip install jmespath
      
      import jmespath
      
      d = {"hoge": {"fuga": {"piyo": 1}}}
      
      v = jmespath.search("hoge.fuga.piyo", d)
      # v = 1
      

      これでよさそう。

      参考ページ
      https://qtatsu.hatenablog.com/entry/2021/05/08/165510

      1 件の返信 最後の返信 返信 引用 1
      • N
        nagai
        最後に編集した時間

        JavaScriptも同様の問題があり、ライウラリー探したけど、いまいちなので自作しました。
        pythonも多分同じ方法で出来ると思います。

        /**

        • オブジェクトのプロパティの存在チェック&取得
        • パラメータ:
        •   obj  : 任意のオブジェクト
          
        •   path : チェックしたいデータがあるプロパティをパス形式で渡す (フォーマット例 "a.b.c")
          
        • 戻り値:
        •   プロパティにデータがある場合はデータを返し、無い場合はnotExistの指定が無い場合は"undefined"を返す
          

        */
        Object.propatyGet = function(obj, path, notExist=undefined) {
        return path.split('.').reduce((obj, prop) => { return obj && obj[prop] ? obj[prop] : notExist; }, obj);
        }

        1 件の返信 最後の返信 返信 引用 1
        • First post
          Last post