意外とつまづく?Pythonの辞書型の値変更のあれこれ

2023/12/25に公開

はじめに

Pythonの辞書型の値を変更したいと思うことは、しばしばあると思います。
ただPythonの辞書型の値の変更は、意外とハマる部分があります。

今回はPythonの辞書型の値の変更を網羅的に解説してきます。

辞書型のvalueの変更

辞書型の値の変更は比較的簡単です。

値の破壊的な代入ならば、以下のように簡単に実行できます。

d = {'a':1,'b':2,'c':3}
d['a'] = 2

次に辞書の値を1つ増やすことを考えます。

d['a'] += 1 

何も考えずに書くとこうなりますが、これだとダメで、keyaがないときにエラーを返します。

対応策としては、defaultdictを使うか、丁寧にif文を書くことでしょう。(他にもgetを使う等ありますが、今回は省略します。)

from collections import defaultdict
d = defaultdict(int)  # int() は 0 を返すので、デフォルト値は 0 になります
d['a'] += 1

d = {}
if 'a' in d:
    d['a'] += 1
else:
    d['a'] = 1

辞書型のkeyの変更

辞書型のキーの変更は、少しだけ面倒です。

キーを変えるというメソッドがないので、popを組み合わせて以下のように書けます。

#aをxに変更
d = {'a':1,'b':2,'c':3} 
if 'a' in d:
    d['x'] = d.pop('a')

for文による辞書型の変更

さらに厄介なのが、for文と組み合わさったときです。

キーの変更のみでfor文を使うことはありませんが、何かの処理と複合してfor文内で処理を書いた方が都合が良いシチュエーションがあったとします。

すると以下のようにプログラムを書けそうです。

d = {'a':1,'b':2, 'c':3}
for k,v in d.items():
    ### 何かしらの処理
    #
    ###
    if k == 'a':
        d['x'] = d.pop(k)

しかし上記のプログラムは、RuntimeErrorを吐きます。

RuntimeError: dictionary keys changed during iteration

対処法としてはエラー文の記載の通り、辞書のキーの変更はfor文と一緒にしないことです。
ただ現行のプログラムの仕様上、どうしてもそれが叶わない場合は新しい辞書を用意して、以下のようにエラーを回避しましょう。

d = {'a':1,'b':2, 'c':3}
d2 = {} #新しい辞書 
for k,v in d.items():
    ### 何かしらの処理
    #
    ###
    if k == 'a':
        d2['x'] = d.pop(k)
    else:
	d2[k] = v

おわりに

いかがだったでしょうか。
辞書型はよく使うと思いますが、上記のように面倒ポイントもあるので、しっかり仕様を理解して使いましょう。

Discussion