defaultdict入れ子の使い方

12685 ワード

defaultdict入れ子の使い方
記事の目次
  • defaultdict入れ子用法
  • スタート
  • 方法1:初期化対象データ構造
  • 方法2:set default
  • 方法3:collection.defaultdict
  • スタートをきる
    昨日会社で残業しました.このようなデータを処理します.
    {" ": "  ", "  ": "  ", "  ": "  1"}
    {" ": "  ", "  ": "  ", "  ": "  2"}
    {" ": "  ", "  ": "  ", "  ": "  3"}
    {" ": "  ", "  ": "  ", "  ": "  4"}
    ...
    
    {" ": "  ", "  ": "  ", "  ": "  1"}
    {" ": "  ", "  ": "  ", "  ": "  2"}
    {" ": "  ", "  ": "  ", "  ": "  3"}
    ...
    
    {" ": "  ", "  ": "  ", "  ": "  1"}
    {" ": "  ", "  ": "  ", "  ": "  2"}
    {" ": "  ", "  ": "  ", "  ": "  3"}
    ...
    
    当時の需要は、村ごとの症状の数を集計しています.データはリストに入れて一緒に返します.
    方法1:イニシャル先データ構造
    最初に思いつく方法は、手動でデータ構造を初期化することです.
    count = {
      "  ": {
        "  ": 0,
        "  ": 0,
        ...
      },
      "  ": {
        ...
      },
      ...
    }
    
    このようにして、サンプルデータを遍歴して直接アキュムレータ操作ができます.
    for item in sample_data:
        count[item[" "]][item["  "]] += 1
    
    しかし、どの村がどんな病気なのかは予め分かりませんでした.countを初期化することができませんでした.もちろんいけないわけではないですが、一応データ構造を見回して、セットで村と症状の値を記録すればいいです.確かに、その時はそうしたくなかったです.
    方法2:setdefaultdict.setdefault(k, new_v)方法の役割は、キーkがあれば、kに対応するv値を返すことである.kがないなら、辞書にキーを付けます.対応値はnew_です.v,kに対応するnew_に同時に戻ります.vです
    そのロジックは簡単です.私達も実現できます.
    def my_setdefault(dic, k, v):
        if k in dic:
            pass
        else:
            dic[k] = v
        return dic[k]        
    
    setdefaultを利用するのはif…elseを使うよりも簡潔に見えるのです.
    count = {}
        for item in sample_data:
            vill = item[" "]
            ill = item["  "]
    
            count.setdefault(vill, {})
            count[vill].setdefault(ill, 0)
    
            count[vill][ill] += 1
    
    コードだけ見ると邪魔になります.実は昨日のプロジェクトは急がなければなりませんでした.もっといい方法が思いつかなかったです.この方法を使いました.
    方法3:collection s.defaultdict
    昨日プロジェクトでsetdefaultを使う前に、collection.defaultdictを考えました.それを使うのは確かに便利です.自分で初期化する必要がないので、直接累積できます.しかし、当時の需要は辞書の入れ子だったので、count = defaultdict(defaultdict(int))を試してみましたが、もちろんできませんでした.プログラム投げ異常:
    TypeError: first argument must be callable or None
    
    このエラーは明らかに外層のdefaultdictが持ち出したものだと今日は思っています.defaultdictは呼び出しができないからです.それを呼び出せばいいじゃないですか?そこでパーティーバイアス関数が登場しました.
    count = defaultdict(
        partial(defaultdict, int)
    )
    for item in sample_data:
        count[item[" "]][item["  "]] += 1
    
    私は試してみる気持ちでrunをクリックします.プログラムは正常に実行されます.
    つまり、partial関数を利用してdefaultdictを入れ子にして使うことができます.上述のような要求を処理すると、コードは簡潔に多くなります.