4.

Python dict から要素を削除する 5 つの方法(del / pop / popitem / clear / 内包表記)

編集
この記事の要点
  • del d['key'] — 一番直接的。キー無いと KeyError
  • d.pop('key', default) — 戻り値が値、default を指定すれば KeyError 回避
  • d.popitem() — 末尾要素 (Python 3.7+ は挿入順最後) を削除
  • d.clear() — 全要素を消す。d = {} と違い同じ参照のまま空に
  • 条件で複数キー削除は内包表記で新しい dict を作る方が安全(イテレート中の削除は危険)

5 つの削除方法

方法戻り値キー無いとき用途
del d['k']なしKeyErrorキーが必ずある前提
d.pop('k')削除した値KeyError値を使いたい場合
d.pop('k', None)削除した値 or defaultdefault を返す安全に削除
d.popitem()(key, value) タプルKeyError (空 dict)末尾削除(LIFO)
d.clear()なし全クリア

1. del

d = {'a': 1, 'b': 2, 'c': 3}
del d['a']
print(d)        # {'b': 2, 'c': 3}

# キーが無いと KeyError
del d['x']      # KeyError: 'x'

# 安全に消したい場合は in でチェック
if 'x' in d:
    del d['x']

2. pop() — 値を取得しつつ削除

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

# 値を取得して削除
v = d.pop('a')
print(v)        # 1
print(d)        # {'b': 2, 'c': 3}

# キー無い + default 無し → KeyError
d.pop('x')      # KeyError: 'x'

# default 指定で安全削除
v = d.pop('x', None)
print(v)        # None
print(d)        # {'b': 2, 'c': 3}

# よくあるイディオム
config = {'host': 'localhost', 'port': 8080}
port = config.pop('port', 80)   # 取り出しつつ削除

3. popitem() — 最後の要素を取り出す

Python 3.7 以降、辞書は挿入順を保持します。popitem()最後に追加された要素を削除して返します。

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

k, v = d.popitem()
print(k, v)     # 'c' 3
print(d)        # {'a': 1, 'b': 2}

# 空辞書では KeyError
d.popitem()     # OK
d.popitem()     # OK
d.popitem()     # KeyError: 'dictionary is empty'

# 全要素取り出しイテレーション(LIFO)
while d:
    k, v = d.popitem()
    print(f'{k} = {v}')

4. clear() — 全部消す

d = {'a': 1, 'b': 2}
d.clear()
print(d)        # {}

# clear と {} 代入の違い (重要)
d1 = {'a': 1}
d2 = d1         # 同じ dict を参照
d1.clear()      # 元 dict を空に → d2 も空
print(d2)       # {}

d1 = {'a': 1}
d2 = d1
d1 = {}         # 新しい空 dict を d1 に代入 → d2 は元のまま
print(d2)       # {'a': 1}

5. 条件で複数キー削除 — 内包表記が安全

イテレート中の dict を del すると RuntimeError になります:

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

# ❌ NG: イテレート中の削除
for k in d:
    if d[k] % 2 == 0:
        del d[k]
# RuntimeError: dictionary changed size during iteration

# ✅ OK 1: キーをリスト化してから
for k in list(d.keys()):
    if d[k] % 2 == 0:
        del d[k]

# ✅ OK 2: 内包表記で新しい dict
d = {k: v for k, v in d.items() if v % 2 != 0}
print(d)        # {'a': 1, 'c': 3}

# ✅ OK 3: 残すキーのリストで filter
keep_keys = {'a', 'c'}
d = {k: v for k, v in d.items() if k in keep_keys}

defaultdict の挙動

defaultdict でも削除は同じですが、削除後にアクセスすると再生成される点に注意:

from collections import defaultdict

d = defaultdict(list)
d['a'].append(1)
print(d)        # defaultdict(<class 'list'>, {'a': [1]})

del d['a']
print(d)        # defaultdict(<class 'list'>, {})

# 削除済みのキーにアクセスすると default で再生成
_ = d['a']
print(d)        # defaultdict(<class 'list'>, {'a': []})

性能比較

操作計算量備考
del d['k'] / pop平均 O(1)ハッシュテーブル
popitem()O(1)末尾削除
clear()O(N)全要素処理
内包表記で再構築O(N)全要素走査

FAQ

Q: ループ中に一部のキーだけ消したい
A: for k in list(d.keys()) で copy を取ってからループ、または内包表記で再構築。直接 for k in d: 中に削除すると RuntimeError。

Q: 値が None の要素だけ消す
A: d = {k: v for k, v in d.items() if v is not None}

Q: 「キーがあれば消す、無くてもエラーにしない」最短は?
A: d.pop('key', None)。1 行で済むしパフォーマンスも良好。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 辞書の作成
  2. 値の参照
  3. 要素の追加と更新
  4. 要素の削除 (辞書 Python)
  5. キーの存在チェック
  6. dictの中身を確認する方法

最近更新/作成されたページ