PythonでKeyErrorが出る理由とは?辞書dictで初心者がハマるポイント
Pythonで辞書を使っていると、突然 KeyError が出てプログラムが止まることがあります。
特に初心者のうちは、リストや文字列の扱いに少し慣れてきたころに辞書が登場し、キーと値という考え方で混乱しやすいです。エラー文に KeyError: 'name' のように表示されても、何が悪いのかすぐにはわからないですよね。
でも、安心してください。
KeyErrorは、原因がわかればかなり対処しやすいエラーです。多くの場合、存在しないキーを取り出そうとしていることが原因です。
この記事では、PythonのKeyErrorが出る理由を、辞書dictの基本から初心者向けにわかりやすく解説します。
PythonのKeyErrorとは?¶
まずは、KeyErrorがどのようなエラーなのかを整理しておきましょう。
KeyErrorは、辞書dictから値を取り出すときに、指定したキーが存在しない場合に発生するエラーです。
辞書dictはキーと値でデータを管理する¶
Pythonの辞書dictは、キーと値をセットで管理するデータ型です。
たとえば、ユーザー情報を辞書で表すと次のようになります。
user = {
"name": "Taro",
"age": 25,
"city": "Tokyo"
}
print(user["name"])
このコードでは、name というキーに Taro という値が入っています。
そのため、user["name"] と書くと、Taro を取り出せます。辞書は、名前をつけて値を管理できる便利な仕組みです。
一方で、存在しないキーを指定するとエラーになります。
user = {
"name": "Taro",
"age": 25
}
print(user["email"])
このコードを実行すると、次のようなエラーが出ます。
KeyError: 'email'
email というキーが辞書の中に存在しないため、Pythonが値を取り出せずに止まってしまいます。
これがKeyErrorです。
KeyErrorはスペルミスでも起きる¶
KeyErrorは、キーが完全に存在しないときだけでなく、スペルミスでも起きます。
user = {
"name": "Taro",
"age": 25
}
print(user["Name"])
このコードでもKeyErrorが出ます。
人間から見ると似ていますが、Pythonでは小文字と大文字は別の文字として扱われます。
つまり、name と Name は別物です。
初心者のうちは、このような小さな違いでハマることがよくあります。エラーが出たら、まずキーの文字が完全に一致しているか確認しましょう。
KeyErrorが出る主な原因¶
ここからは、KeyErrorが出る原因を具体的に見ていきます。
原因を分解すると、対処の仕方も見えやすくなります。
存在しないキーを指定している¶
一番よくある原因は、存在しないキーを指定していることです。
profile = {
"name": "Hanako",
"job": "engineer"
}
print(profile["age"])
この辞書には、name と job はあります。
しかし、age はありません。そのため、profile["age"] と書くとKeyErrorになります。
辞書から値を取り出すときは、そのキーが本当に存在するかを意識する必要があります。
キーの名前を間違えている¶
次に多いのが、キー名の間違いです。
item = {
"price": 1200,
"stock": 5
}
print(item["prcie"])
このコードでは、price と書きたいところを prcie と書いています。
プログラムは人間のように、たぶんpriceのことだろうとは判断してくれません。完全一致で探すため、1文字でも違うと別のキーとして扱われます。
エンジニア歴10年の今でも、私はこうしたタイプミスをします。
大事なのは、ミスをしないことではありません。エラーを見たときに、キー名を確認する習慣を持つことです。
辞書の中身が想定と違っている¶
初心者が少しステップアップしたころにハマりやすいのが、辞書の中身が想定と違うケースです。
たとえば、APIやJSONから取得したデータを扱うときによく起きます。
user = {
"id": 1,
"name": "Taro"
}
print(user["email"])
自分では、ユーザー情報にはメールアドレスが入っているはずだと思っていても、実際のデータには入っていないことがあります。
この場合も、email が存在しないためKeyErrorになります。
APIや外部データを扱うときは、必ずしもすべてのキーが入っているとは限りません。ここは実務でもかなり大切です。
ネストした辞書で途中のキーがない¶
辞書の中に辞書が入っている形を、ネストした辞書と呼ぶことがあります。
user = {
"name": "Taro",
"address": {
"city": "Tokyo"
}
}
print(user["address"]["zip"])
このコードでは、address は存在します。
しかし、address の中に zip というキーはありません。そのため、user["address"]["zip"] でKeyErrorになります。
ネストした辞書では、どの階層のキーが存在しないのかを確認することが大切です。
KeyErrorの原因を見つける方法¶
KeyErrorが出たときは、焦らずに原因を確認しましょう。
エラー文を全部完璧に読む必要はありません。まずは、どのキーで失敗しているかを見れば十分です。
エラー文の最後を見る¶
KeyErrorが出ると、最後の行に失敗したキーが表示されます。
KeyError: 'email'
この場合、email というキーを取り出そうとして失敗しています。
つまり、辞書の中に email がない可能性が高いです。
まずは、対象の辞書にどんなキーが入っているか確認しましょう。
user = {
"id": 1,
"name": "Taro"
}
print(user.keys())
実行すると、次のような結果になります。
dict_keys(['id', 'name'])
これを見ると、email が入っていないことがわかります。
printで辞書の中身を確認する¶
初心者のうちは、辞書の中身をprintで確認するのが一番わかりやすいです。
user = {
"id": 1,
"name": "Taro"
}
print(user)
中身を表示すると、自分が思っていたデータと実際のデータが違うことに気づけます。
実務でも、デバッグの最初の一歩としてデータの中身を確認することはよくあります。
学習段階では、printで見える化するのは有効です。
KeyErrorを防ぐ基本的な方法¶
KeyErrorは、事前にキーの存在を確認することで防げます。
ここでは、初心者がまず覚えておきたい方法を紹介します。
inでキーが存在するか確認する¶
辞書にキーがあるかどうかは、in を使って確認できます。
user = {
"name": "Taro",
"age": 25
}
if "email" in user:
print(user["email"])
else:
print("emailは登録されていません")
このコードでは、まず email が辞書に存在するか確認しています。
存在する場合だけ値を取り出すため、KeyErrorを防げます。
in はリストや文字列でも使えますが、辞書で使う場合はキーの存在を確認します。ここは覚えておくと便利です。
getメソッドを使う¶
KeyError対策として特に便利なのが、get() メソッドです。
user = {
"name": "Taro",
"age": 25
}
email = user.get("email")
print(email)
このコードでは、email キーが存在しない場合でもKeyErrorにはなりません。
代わりに、None が返ります。
さらに、キーが存在しない場合のデフォルト値も指定できます。
user = {
"name": "Taro",
"age": 25
}
email = user.get("email", "未登録")
print(email)
この場合、email がなければ 未登録 と表示されます。
初心者のうちは、存在するかわからないキーを取り出すときは、get() を使うと安全です。
try-exceptで例外処理する¶
KeyErrorが起きる可能性がある処理を、try-exceptで受け止める方法もあります。
user = {
"name": "Taro",
"age": 25
}
try:
print(user["email"])
except KeyError:
print("emailキーが見つかりませんでした")
このコードでは、user["email"] でKeyErrorが起きても、プログラム全体は止まりません。
代わりに、exceptの中の処理が実行されます。
ただし、何でもtry-exceptで囲めばいいわけではありません。
キーが存在しないことが普通にありえるなら get()、エラーとして扱いたいならtry-except、という使い分けを意識しましょう。
KeyError対策の使い分け¶
ここで、代表的な対策方法を表で整理しておきます。
どの方法を使うべきか迷ったときの参考にしてください。
| 方法 | 書き方 | 向いている場面 |
|---|---|---|
| 直接アクセス | user["name"] |
キーが必ず存在するとわかっている |
| inで確認 | "name" in user |
存在確認してから処理したい |
| getを使う | user.get("name") |
キーがない場合も自然に処理したい |
| getのデフォルト値 | user.get("email", "未登録") |
表示用の代替値を用意したい |
| try-except | except KeyError |
キーがないことを例外として扱いたい |
この表を見ると、すべての場面で同じ書き方をする必要はないことがわかります。
まずは、直接アクセスとgetの違いを理解できれば十分です。
初心者がハマりやすい辞書dictのポイント¶
KeyErrorを理解するには、辞書そのものの特徴も押さえておく必要があります。
ここでは、初心者がよく混乱するポイントを紹介します。
辞書は順番よりキーで取り出す¶
リストは、0番目、1番目、2番目のように位置で値を取り出します。
fruits = ["apple", "banana", "orange"]
print(fruits[0])
一方、辞書はキーで値を取り出します。
user = {
"name": "Taro",
"age": 25
}
print(user["name"])
リストの感覚で辞書を扱うと、混乱しやすくなります。
辞書は、名前付きのデータを管理するものと考えると理解しやすいです。
キーには文字列以外も使える¶
辞書のキーには、文字列以外も使えます。
scores = {
1: 80,
2: 95,
3: 70
}
print(scores[1])
このコードでは、数値の 1 をキーとして使っています。
ここで注意したいのは、数値の 1 と文字列の "1" は別物だということです。
scores = {
1: 80
}
print(scores["1"])
このコードはKeyErrorになります。
人間には同じ1に見えても、Pythonでは数値と文字列は別の型です。input関数で受け取った値は文字列になるため、辞書のキーと型が合わずにハマることもあります。
【関連記事】Pythonのinput関数を初心者向けに解説!キーボード入力を受け取る基本
実務でKeyErrorが起きやすい場面¶
ここからは、実務でKeyErrorが起きやすい場面を紹介します。
早めに知っておくと、実践でかなり役立ちます。
JSONやAPIのレスポンスを扱うとき¶
Pythonでは、APIから取得したJSONデータを辞書として扱うことがあります。
response = {
"status": "ok",
"data": {
"name": "Taro"
}
}
print(response["data"]["email"])
このコードでは、data の中に email がないためKeyErrorになります。
APIのデータは、状況によって含まれるキーが変わります。
そのため、外部データを扱うときは、直接アクセスしすぎない方が安全です。
data = response.get("data", {})
email = data.get("email", "未登録")
print(email)
このように書くと、キーがない場合でも安全に処理できます。
CSVやExcelから読み込んだデータを扱うとき¶
CSVやExcelのデータを辞書として扱う場合も、KeyErrorが起きることがあります。
たとえば、列名が想定と違うケースです。
row = {
"氏名": "山田太郎",
"年齢": 30
}
print(row["名前"])
この場合、辞書にあるキーは 氏名 ですが、コードでは 名前 を指定しています。
意味としては近くても、Pythonでは別のキーです。そのためKeyErrorになります。
実務では、列名の表記ゆれが原因になることがよくあります。
氏名、名前、Name、nameのように、同じ意味でも表記が違うと別物として扱われます。
エンジニア歴10年の私が思うKeyErrorとの向き合い方¶
ここで、少し実務目線の話をします。
エンジニア歴10年の中で、KeyErrorは何度も見てきました。初心者だけでなく、実務でも普通に出るエラーです。
大切なのは、KeyErrorを単なるミスとして片付けないことです。
KeyErrorが出たときは、データの前提が間違っている可能性があります。
コードだけでなく、扱っているデータの形も確認する必要があります。
私は実務で辞書を扱うとき、まずキーが必ず存在するのか、存在しない可能性があるのかを考えます。
必ず存在する前提なら、直接アクセスでもよいです。
一方で、外部から来るデータなら、getやinで確認することが多いです。データは思ったよりきれいではありません。
初心者のうちから、データはいつも完璧とは限らないという感覚を持っておくと、かなり強くなります。
KeyErrorを減らすための学習ポイント¶
KeyErrorを減らすには、辞書の扱いに慣れることが一番です。
最初は難しく感じるかもしれませんが、短いコードで何度も試すと理解しやすくなります。
小さな辞書を自分で作って試す¶
まずは、小さな辞書を自分で作ってみましょう。
book = {
"title": "Python入門",
"price": 1800,
"author": "Yamada"
}
print(book["title"])
print(book.get("publisher", "出版社未登録"))
このコードでは、存在するキーと存在しないキーの両方を試しています。
自分でキーを追加したり、スペルを変えたりすると、KeyErrorの感覚がつかめます。
エラーをあえて出してみる¶
学習段階では、あえてKeyErrorを出してみるのもおすすめです。
menu = {
"coffee": 300,
"tea": 250
}
print(menu["juice"])
このコードはKeyErrorになります。
次に get() に書き換えてみましょう。
print(menu.get("juice", "メニューにありません"))
エラーが出る書き方と出ない書き方を比べると、理解がかなり進みます。
まとめ¶
PythonのKeyErrorは、辞書dictから存在しないキーを取り出そうとしたときに発生します。
初心者がハマりやすい原因には、キーのスペルミス、大文字小文字の違い、辞書の中身が想定と違うこと、ネストした辞書のキー不足などがあります。
まずは、エラー文の最後に表示されるキーを確認しましょう。
そのうえで、print(user.keys()) や print(user) を使って、辞書の中身を確認します。
KeyErrorを防ぐには、in でキーの存在を確認したり、get() を使って安全に値を取り出したりする方法があります。キーが存在しないことを例外として扱いたい場合は、try-exceptも使えます。
大切なのは、辞書はキーで値を取り出すデータ型だと理解することです。
リストのように位置で取り出すのではなく、キーの名前を正しく指定する必要があります。
KeyErrorは、初心者だけでなく実務でもよく出るエラーです。
だからこそ、早い段階で原因と対処法を知っておく価値があります。エラーが出ても焦らず、どのキーが存在しないのかを1つずつ確認していきましょう。