Code Fix

中級

KeyError の原因と直し方

辞書に存在しないキーへアクセスしたときに出るエラーです。大文字小文字の違いも別のキーとして扱われます。

エラーメッセージの読み方

Traceback (most recent call last):
main.py
ファイル名
2
行番号 — 実際にクラッシュした行
<module>
発生場所 — <module> ならトップレベル、関数名ならその関数の中
KeyError
例外クラス — 何が起きたか。ここを検索するのが最短です
'email'
詳細メッセージ — どの値が問題だったか

このエラーが出る典型パターン

パターン1

 1  user = {"name": "Tom", "age": 20}
 2  print(user["email"])
                  ^
Traceback (most recent call last): File "main.py", line 2, in <module> print(user["email"]) ~~~~^^^^^^^^^ KeyError: 'email'

辞書に存在しないキーへのアクセスはKeyErrorになります。存在確認をしたい場合は.get()やinで先にチェックします。

直し方: "email" を "name" にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  scores = {"math": 90, "science": 85}
 2  print(scores["Math"   ])
                     ^
Traceback (most recent call last): File "main.py", line 2, in <module> print(scores["Math"]) ~~~~~~^^^^^^^^ KeyError: 'Math'

辞書のキーも大文字小文字を区別します。定義したときと違う大文字小文字を指定すると別のキー扱いになります。

直し方: "Math" を "math" にします。

この問題を解いてみる →

パターン3

 1  config = {"debug": True}
 2  print(config["verbose"])
                     ^
Traceback (most recent call last): File "main.py", line 2, in <module> print(config["verbose"]) ~~~~~~^^^^^^^^^^^ KeyError: 'verbose'

存在しないキーを指定する典型的な原因は、綴りの思い違いや設定項目名の勘違いです。

直し方: "verbose" を "debug" にします。

この問題を解いてみる →

パターン4

 1  user = {"profile": {"city": "Tokyo"}}
 2  print(user["profile"]["country"])
                              ^
Traceback (most recent call last): File "main.py", line 2, in <module> print(user["profile"]["country"]) ~~~~~~~~~~~~~~~^^^^^^^^^^^ KeyError: 'country'

辞書がネストしていても規則は同じです。内側の辞書に存在しないキーを指定するとKeyErrorになります。

直し方: "country" を "city" にします。

この問題を解いてみる →

パターン5

 1  prices = {"apple": 100, "banana": 50}
 2  total = prices["apple"] + prices["orange"]
                                         ^
 3  print(total)
Traceback (most recent call last): File "main.py", line 2, in <module> total = prices["apple"] + prices["orange"] ~~~~~~^^^^^^^^^^ KeyError: 'orange'

複数のキーを扱う式の一部で存在しないキーを使うと、式全体の評価がそこで止まります。

直し方: "orange" を "banana" にします。

この問題を解いてみる →

よくある誤解

IndexErrorと混同されがちですが、こちらは辞書(キーによるアクセス)専用のエラーです。存在確認をしたい場合はin演算子か.get()を使います。

実務での勘所

存在しないかもしれないキーを扱う方法は複数あり、場面によって使い分けます。if key in d: の後にd[key]と読む書き方は分かりやすい一方、辞書を2回検索することになります。d.get(key, default)は1回の検索で済み、見つからない場合の既定値もその場で指定できます。さらに「無ければ新しく作ってから使う」場面が多いなら、collections.defaultdictを使えば、存在しないキーへのアクセス自体が自動的に既定値を作ってくれるため、KeyErrorの心配自体が要らなくなります。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)