SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

ネストした辞書(連想配列)の「初期化・全件処理・JSON保存・復元」/Python文法

f:id:arakan_no_boku:20190427205325j:plain

目次

ネストした辞書

例えば、「A,B,C,Dの4つのテキストデータに登場する単語の割合をそれぞれ保持する」みたいなことをする場合、以下のようにキーが2段階の辞書に収めることになります。

これを「ネストした辞書」とよんでます。

word_dic['単語']['A']  = 0.035

word_dic['単語']['B']  = 0.236

word_dic['単語']['C']  = 0.432

word_dic['単語']['D']  = 0.065

こういう「ネストした辞書」は、初期化・更新・一覧などで、ネストしない場合と少々勝手が違います。

初期化

制的な初期化

2段にネストした辞書の初期化です。

{'幸せ':

  {'pcount': 0, 'ncount': 0, 'prate': 0, 'nrate': 0}

}

動的な初期化

setdefault()を使うスタンダードな方法です。

keyA = 'pcount'
keyB = 'ncount'
keyC = 'prate'
keyD = 'nrate'
word = '幸せ'

word_dic = {}
word_dic.setdefault(word,{})
word_dic[word].setdefault(keyA,0)
word_dic[word].setdefault(keyB,0)
word_dic[word].setdefault(keyC,0)
word_dic[word].setdefault(keyD,0)
__missing__を実装 

__missing__を実装した拡張dictクラスを作る方法です。

class MyDict(dict):
def __missing__(self,key):
    v = self[key] = type(self)()
    return v

 

上記のようにクラスを作っておけば以下のように初期化できるようになります。

w_dic = MyDict()
w_dic[word]
w_dic[word][keyA] = 0
w_dic[word][keyB] = 0
w_dic[word][keyC] = 0
w_dic[word][keyD] = 0
 

全件処理

ネストした辞書をforループでまわすときは、再帰で処理してやる必要があります。 

とりあえず、全部の要素を書き出す処理の例です。

関数にして、インスタンスを調べて辞書だったら、再帰呼出しです。

def recursive_dict(argd):
    for k in sorted(argd.keys(),reverse=False):
        if(isinstance(argd[k],dict)):
            recursive_dict(argd[k])
        else:
            print("key is {0}/value is{1}".format(k,argd[k]))

 

この出力はこんな感じになります。

key is ncount/value is0.7332
key is nrate/value is0.4568
key is pcount/value is20
key is prate/value is12
key is ncount/value is0
key is nrate/value is0
key is pcount/value is0
key is prate/value is0

保存・復元

JSON形式 で保存

ネストした辞書は、JSON形式で保存しておくと、復元も超簡単です。 

まず、保存します。

import json
fw = open('test.json','w')
json_data = json.dump(w_dic,fw,indent=4)
fw.close()

 

これだけで、test.jsonというファイルがカレントフォルダにできます。

JSONファイルから復元 

こんどは、保存したファイルから辞書を復元します。

fr = open('test.json','r')
r_dic = json.load(fr)
fr.close()

 

これでr_dicに、辞書が復元できてます。

{'幸せ': {'pcount': 20, 'ncount': 0.7332, 'prate': 12, 'nrate': 0.4568}, '当たり前': {'pcount': 20, 'ncount': 0.7332, 'prate': 12, 'nrate': 0.4568}} 

これくらいできれば、ネストした辞書を使って、普通のことはできます。

ではでは。