2
5

More than 3 years have passed since last update.

Pythonで一度に、安全に、非破壊的に、複数辞書の結合と複数要素の追加を行う

Posted at

やりたいこと

  • 複数の辞書を結合して1つの辞書にしたい
  • ついでに他にも要素を追加したい
dictA = {'A1': 1, 'A2': 1}
dictB = {'B1': 1, 'B2': 1}
# ---(辞書の結合 & 要素の追加)---
# => {'key1': 1, 'key2': 1, 'A1': 1, 'A2': 1, 'B1': 1, 'B2': 1}

さらに、

  • 非破壊的に (元の辞書に変更を加えずに) 処理したい
  • valueの変更をしない (keyが重複していたらエラーになってほしい)

これらを実現するための効率の良い書き方を紹介したいと思います。

良くない書き方

これは、.update()と辞書の追加記法を使えば一部実現可能です。

dictA.update(dictB)
dictA['key1'] = 1
dictA['key2'] = 1
new_dict = dictA 
print(new_dict)
# => {'A1': 1, 'A2': 1, 'B1': 1, 'B2': 1, 'key1': 1, 'key2': 1}

デメリット

元のdictAはなくなってしまいます。(dictAに要素の追加 (破壊的変更) をしているため)

print(dictA)
# => {'A1': 1, 'A2': 1, 'B1': 1, 'B2': 1, 'key1': 1, 'key2': 1}

また、keyが重複していると値が上書きされます。これは意図せぬ挙動(バグの原因)を引き起こす可能性があります。

dictA = {'key': 'dictA'}
dictB = {'key': 'dictB'}
dictA.update(dictB)
print(dictA)
# => {'key': 'dictB'}

適切な書き方

結合や要素の追加ということを気にせず、dict関数のキーワード引数に値を渡して新たに辞書をつくります。何個でも可能です。

new_dict = dict(
    key1=1,
    key2=1,
    **dictA,
    **dictB,
)
print(new_dict)
# => {'key1': 1, 'key2': 1, 'A1': 1, 'A2': 1, 'B1': 1, 'B2': 1}

非破壊的

非破壊的な処理なので元の辞書は変更を受けません。

new_dict['keyA1'] = 5

print(new_dict['keyA1'])
# => 5
print(dictA['keyA1'])
# => 1

重複がある場合の挙動

重複がある場合はTypeErrorになるので、意図しない値の上書きを回避できます。
辞書内のkeyと明示的に書いたキーワード引数すべての重複に対してエラーになります。

dictA = {'key': 'dictA'}
dictB = {'key': 'dictB'}

new_dict = dict(
    key='A',
    **dictA,
    **dictB,
)
# => TypeError: type object got multiple values for keyword argument 'key'

まとめ

dict関数で作り直せば辞書の結合、要素の追加は安全かつ簡潔に書けますよ、という話でした!

2
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5