Pythonで階層dictをコピーして使う
Page content
Pythonでdictをコピーして使うときの諸々。
dictは参照渡し
同じ初期値のdictを複数作り、それぞれ別で使いたいことがある。
その際、普通にdictを渡すと、参照先が同じになってしまう。
>>> ichiro = {'打率': '', '本塁打': ''}
>>> saburo = ichiro
>>> ichiro['打率'] = '.400'
>>> ichiro
{'打率': '.400', '本塁打': ''}
>>> saburo
{'打率': '.400', '本塁打': ''}
copyを使う
copy
を使って複製すれば、新たなdictを作る。
>>> ichiro = {'打率': '', '本塁打': ''}
>>> saburo = ichiro.copy()
>>> ichiro['打率'] = '.400'
>>> ichiro
{'打率': '.400', '本塁打': ''}
>>> saburo
{'打率': '', '本塁打': ''}
ただし、dictが階層構造の場合、子dictの参照先が同じになってしまう。
>>> ichiro = {'打率': '', '本塁打': '', '対右': {'打率': '', '本塁打': ''}}
>>> saburo = ichiro.copy()
>>> ichiro['打率'] = '.400'
>>> ichiro['対右']['打率'] = '.450'
>>> ichiro
{'打率': '.400', '本塁打': '', '対右': {'打率': '.450', '本塁打': ''}}
>>> saburo
{'打率': '', '本塁打': '', '対右': {'打率': '.450', '本塁打': ''}}
deepcopyを使う
この場合、copy.deepcopy
を使うことで、子dictまで複製することができる。
>>> import copy
>>> ichiro = {'打率': '', '本塁打': '', '対右': {'打率': '', '本塁打': ''}}
>>> saburo = copy.deepcopy(ichiro)
>>> ichiro['打率'] = '.400'
>>> ichiro['対右']['打率'] = '.450'
>>> ichiro
{'打率': '.400', '本塁打': '', '対右': {'打率': '.450', '本塁打': ''}}
>>> saburo
{'打率': '', '本塁打': '', '対右': {'打率': '', '本塁打': ''}}
内包表記で作る
内包表記で複数作っておいて渡す、というのもある。たくさん作るならこちらのほうが便利。
>>> list = [{'打率': '', '本塁打': '', '対右': {'打率': '', '本塁打': ''}} for _ in range(2)]
>>> ichiro = list[0]
>>> saburo = list[1]
>>> ichiro['打率'] = '.400'
>>> ichiro['対右']['打率'] = '.450'
>>> ichiro
{'打率': '.400', '本塁打': '', '対右': {'打率': '.450', '本塁打': ''}}
>>> saburo
{'打率': '', '本塁打': '', '対右': {'打率': '', '本塁打': ''}}
このケースならdict内包表記で作っておくのが一番楽そう。
>>> dic = {player: {'打率': '', '本塁打': '', '対右': {'打率': '', '本塁打': ''}} for player in ['ichiro', 'saburo']}
>>> dic['ichiro']['打率'] = '.400'
>>> dic['ichiro']['対右']['打率'] = '.450'
>>> dic
{'ichiro': {'打率': '.400', '本塁打': '', '対右': {'打率': '.450', '本塁打': ''}}, 'saburo': {'打率': '', '本塁打': '', '対右': {'打率': '', '本塁打': ''}}}
おわり
参照渡しなので、returnしたりしなくても適宜dictを更新していけるのは楽。
ただし、初期dictを複数の場所で使うような場合は注意が必要になる。