LoginSignup
7
12

More than 5 years have passed since last update.

Python の辞書で条件に一致するキーと値を削除する

Last updated at Posted at 2018-12-29

お題

辞書で特定のキーを持つ要素を除くケースを考える。ただし、次の条件をどちらも満たしている。

  • 辞書の中身が事前に分からない
  • 対象のキーは two だが、大文字小文字を区別しない

例えば次のような結果となる。

import pprint

dic = {'one': 1, 'two': 2, 'three': 3}
# 削除処理
# pprint.pprint(dic)
# => {'one': 1, 'three': 3}

dic = {'one': 1, 'TWO': 2, 'three': 3}
# 削除処理
# pprint.pprint(dic)
# => {'one': 1, 'three': 3}

dic = {'one': 1, 'Two': 2, 'three': 3}
# 削除処理
# pprint.pprint(dic)
# => {'one': 1, 'three': 3}

次の記述でOK

dic = {k: v for k, v in dic.items() if k.lower() != 'two'}

# pprint.pprint(dic)
# => {'one': 1, 'three': 3}

イテレータを使う場合は Python 2.x と 3.x の互換性を考慮して six を使う事を検討したい。

import six

dic = {k: v for k, v in six.iteritems(dic) if k.lower() != 'two'}

# pprint.pprint(dic)
# => {'one': 1, 'three': 3}

リスト内包表記を使用しない場合は要注意

リスト内包表記を使用しない場合、次の記述で良さそうに思える。

for k, v in dic.items():
    if k.lower() == 'two':
      dic.pop(k, None)

Python 2.x では問題ないが、Python 3.x では次のエラーが発生する。

Traceback (most recent call last):
  File "delete_if.py", line 4, in <module>
    for k, v in dic.items():
RuntimeError: dictionary changed size during iteration

代わりに次のように記述する。

for k, v in list(dic.items()):
    if k.lower() == 'two':
      dic.pop(k, None)

値は取り出しても参照しないのであれば、次の記述の方がシンプルになる。

for k in list(dic.keys()):
    if k.lower() == 'two':
      dic.pop(k, None)

さらにイテレータを使う場合は次のようになる。

import six

for k in list(six.iterkeys(dic)):
    if k.lower() == 'two':
      dic.pop(k, None)
7
12
3

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
7
12