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を複数の場所で使うような場合は注意が必要になる。