Python の dict アクセスで KeyError が解消できない
KeyError は dict に存在しないキーを d[key] で参照したときに発生する。
事前チェックなら `if key in d`、デフォルト値を返すなら d.get(key, default)、欠落キーを許容したいなら collections.defaultdict を使い分ける。
スペース・改行・大文字小文字違いが原因のことも多い。
公開:
要約
KeyError は dict に存在しないキーを d[key] で参照したときに必ず発生する例外。
回避策は 3 つ: 事前に key in d で確認する、d.get(key, default) でデフォルト値を返す、collections.defaultdict で「キーが無ければ自動で空値を作る」運用にする。
例外メッセージにキー名がそのまま出るので、見えない空白や改行が混じっていないかも要確認。
よくある原因
- API レスポンスや JSON の構造が想定と違う。
OpenAPI でrequiredでないフィールドをd["foo"]で取りに行って落ちる。 - CSV ヘッダや環境変数の読み込み時に、末尾の改行や半角スペースが残ったままキーになっている。
- HTTP ヘッダや YAML の dict は大文字小文字の扱いが処理系で違う。
d["Content-Type"]とd["content-type"]は別キー。 - for ループの中で
d[f"item_{i}"]のようにキーを組み立てるとき、iの範囲が dict にない値まで含む。
解決策
1. d.get() を使う
value = d.get("name") # 無ければ None
value = d.get("name", "anon") # 無ければ "anon"公式ドキュメント(新しいタブで開く) の挙動どおり、例外を出さずに済む。
戻り値が None になり得る点に注意し、後段の属性アクセス前に is not None で絞ると安全。
2. in で先にチェックする
if "name" in d:
print(d["name"])「キーがあるときだけ何かする」明示的なフローを書きたい場合はこちら。
3. defaultdict で初期値を任せる
from collections import defaultdict
counts = defaultdict(int)
for word in words:
counts[word] += 1 # 初出キーは 0 から開始リスト追加なら defaultdict(list)、ネスト dict なら defaultdict(dict) を使う。
挙動の詳細は collections 公式ドキュメント(新しいタブで開く) を参照。
4. キー文字列を正規化する
clean = {k.strip().lower(): v for k, v in raw.items()}
clean["content-type"]CSV / 環境変数 / HTTP ヘッダから dict を作るときは、読み込み直後に空白除去と小文字化をしておくと「見えないバグ」を予防できる。
実行例
実際に上記の手順を python:3.12(Debian GNU/Linux 13 trixie)環境で動かすと、d["email"] へのアクセスで KeyError: 'email' が発生し(終了コード 1)、続いて d.get()・in チェック・defaultdict の 3 つの解消策がいずれも正常に動作することを確認できる。
== versions ==
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
Python 3.12.13
git version 2.47.3
== run ==
--- python bad.py (KeyError: "email" を想定)---
Traceback (most recent call last):
File "/tmp/tmp.9cAOvd641l/bad.py", line 2, in <module>
print(d["email"])
~^^^^^^^^^
KeyError: 'email'
終了コード: 1
--- 解消1: d.get() でデフォルト値を返す ---
get なし既定 : None
get 既定指定 : no-email@example.com
--- 解消2: in でキー存在を先に確認する ---
name = alice
email は dict に無い
--- 解消3: collections.defaultdict で自動初期化 ---
{'apple': 3, 'banana': 2, 'cherry': 1}— 2026-07-01 時点の出力