Last Updated on 2025年7月28日
概要
Pythonで辞書(dict)を操作している際に発生するエラー「RuntimeError: dictionary changed size during iteration」は、多くの初心者がつまずくポイントの1つです。このエラーは、辞書のサイズがイテレーション中に変更されたときに発生します。つまり、ループで辞書を走査中に、要素を追加・削除することで矛盾が起こり、Pythonがそれを検出してエラーを投げる仕組みです。
目次
エラー内容
このエラーは以下のような形で出力されます。
|
1 |
RuntimeError: dictionary changed size during iteration |
たとえば、以下のようなコードを実行した場合に発生します。
|
1 2 3 4 5 |
my_dict = {'a': 1, 'b': 2, 'c': 3} for key in my_dict: if key == 'b': del my_dict[key] |
原因
このエラーが出る理由は明確です。Pythonでは辞書のサイズをイテレーション中に変更してはいけません。ループ中にdelやpopで要素を削除したり、my_dict[key] = valueのように追加した場合、辞書の内部構造が変わってしまうため、安全性の観点からエラーとして検出されます。
以下はサイズ変更を行う操作の例です:
del dict[key](要素の削除)dict.pop(key)(要素の削除)dict[new_key] = value(要素の追加)
対処法
エラーを回避するには、以下のような方法が考えられます。
1. 辞書のコピーを使う
|
1 2 3 4 5 |
my_dict = {'a': 1, 'b': 2, 'c': 3} for key in list(my_dict): if key == 'b': del my_dict[key] |
list(my_dict)によって辞書のキーだけを一時的なリストとして取り出し、それをループさせることで、元の辞書に変更を加えてもエラーになりません。
2. 削除対象のキーを一度リストにまとめてから削除
|
1 2 3 4 5 6 7 8 9 |
my_dict = {'a': 1, 'b': 2, 'c': 3} to_delete = [] for key in my_dict: if key == 'b': to_delete.append(key) for key in to_delete: del my_dict[key] |
この方法では、イテレーション中に辞書を変更せず、一度リストに削除対象をためておいて、ループ終了後に削除するので安全です。
3. 辞書内包表記を使ってフィルター
|
1 2 |
my_dict = {'a': 1, 'b': 2, 'c': 3} my_dict = {k: v for k, v in my_dict.items() if k != 'b'} |
条件に合わないキーを除いた新しい辞書を作成することで、元の辞書に変更を加えずに済みます。
補足
このエラーは、辞書だけでなく、セット(set)などの他のミュータブルなデータ構造でも類似のエラーが出ることがあります。たとえば:
|
1 2 3 |
my_set = {1, 2, 3} for item in my_set: my_set.remove(item) # RuntimeErrorが発生 |
同じように、コピーしてから操作するのがベストです。
また、Pythonのバージョンによっても挙動が多少異なる場合がありますが、基本的にはどのバージョンでも同様の対処法で問題は解決できます。
まとめ
「RuntimeError: dictionary changed size during iteration」は、Pythonで辞書を操作中にサイズを変更してしまうと発生するエラーです。初心者にとってはわかりにくいエラーですが、イテレーション中に辞書を変更しないという原則を守ることで防ぐことができます。
対処法としては、辞書のコピーや一時的なリストに退避する方法、内包表記での再生成などが有効です。構造的に安全なコードを書くことが、パフォーマンスだけでなくバグのないプログラム作成にもつながります。


