Python で反復処理中に辞書から項目を削除できますか?
完全に新しい辞書を作成するのではなく、特定の条件を満たさない要素を辞書から削除したいと思います。次の方法は良い解決策でしょうか、それとももっと良い方法があるでしょうか?
for k, v in mydict.items():
if k == val:
del mydict[k]
ベストアンサー1
Python 3+の場合:
>>> mydict
{'four': 4, 'three': 3, 'one': 1}
>>> for k in list(mydict.keys()):
... if mydict[k] == 3:
... del mydict[k]
>>> mydict
{'four': 4, 'one': 1}
他の回答はPython 2では問題なく動作しますが、Python 3RuntimeError
では問題が発生します。
RuntimeError: 反復中に辞書のサイズが変更されました。
これは、mydict.keys()
リストではなくイテレータを返すために発生します。コメントで指摘されているように、単にmydict.keys()
リストに変換するだけで動作list(mydict.keys())
するはずです。
Python 2の場合:
コンソールでの簡単なテストでは、反復処理中に辞書を変更できないことがわかります。
>>> mydict = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
>>> for k, v in mydict.iteritems():
... if k == 'two':
... del mydict[k]
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
delnan の回答で述べられているように、エントリを削除すると、イテレータが次のエントリに移動しようとしたときに問題が発生します。代わりに、keys()
メソッドを使用してキーのリストを取得し、それを使用して作業します。
>>> for k in mydict.keys():
... if k == 'two':
... del mydict[k]
>>> mydict
{'four': 4, 'three': 3, 'one': 1}
アイテムの値に基づいて削除する必要がある場合は、items()
代わりに次のメソッドを使用します。
>>> for k, v in mydict.items():
... if v == 3:
... del mydict[k]
>>> mydict
{'four': 4, 'one': 1}