辞書を反復処理しながら項目を削除するにはどうすればいいですか? 質問する

辞書を反復処理しながら項目を削除するにはどうすればいいですか? 質問する

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}

おすすめ記事