Python KeyError
Core Python Errors and Exceptions Error explained

Python KeyError: What It Means and How to Fix It

1Python KeyError: overview

A KeyError is raised when you use square brackets to ask a dictionary for a key it does not contain, like user["phone"] when there is no "phone" key.

GoalBy the end you can read a KeyError and its traceback, track down why a key is missing, and choose the right fix: get(), in, setdefault(), defaultdict or try/except.

Before this lesson: Python Dictionaries, Python Exceptions: try, except, else and finally

2Python KeyError: diagram

Python KeyError: What It Means and How to Fix Ituserkeysvalues"name""Asha""email""asha@mail.com""age"21user["phone"] -> KeyError: 'phone' (no such key here; "Email" fails too)
A dictionary only has the keys you put in it. There is no "phone" box, so user["phone"] raises KeyError. Keys must also match exactly, so user["Email"] with a capital E fails as well.

3Python KeyError: explained step by step

A dictionary finds values by key. Writing user["email"] tells Python "this key definitely exists". If it doesn't, Python won't make up a value. It raises a KeyError, and the message is simply the key it couldn't find, such as KeyError: 'phone'.

How to read the traceback

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    print(user["phone"])
          ~~~~^^^^^^^^^
KeyError: 'phone'

The last line shows the exact key Python searched for, in quotes if it's a string. The line above it shows where the lookup happened, and the ^^^ marks the key inside the brackets. Now compare that key, character by character, with the keys the dictionary really has. print(list(user)) lists them. Watch out for capital letters, stray spaces and quotes: KeyError: 1 means you looked up the number 1, while KeyError: '1' means the string "1".

Common causes

  1. A typo or different capitalisation. Keys are case-sensitive: "Email", "email" and "email " are three different keys.
  2. Data that doesn't always include the field. Records from JSON files, APIs and forms often leave out optional fields.
  3. A key that was never added, or was removed. Counting with counts[word] += 1 fails the first time a word appears, and del or pop() remove keys your code may still read later.
  4. The wrong key type. JSON object keys are always strings, so after json.loads() you need data["1"], not data[1].

Fixes for reading values

Python
user = {"name": "Asha", "email": "asha@example.com"}

print(user.get("phone"))                # None instead of an error
print(user.get("phone", "not given"))   # or your own default

if "email" in user:                     # check first
    print("Email:", user["email"])

try:
    print(user["Email"])
except KeyError as err:
    print("Missing key:", err)

print("Real keys:", list(user))

Fixes for building a dictionary

When you are filling a dictionary, let Python create missing keys for you:

Python
from collections import defaultdict

words = ["red", "blue", "red", "green", "red"]

counts = {}
for w in words:
    counts[w] = counts.get(w, 0) + 1
print(counts)

by_length = {}
for w in words:
    by_length.setdefault(len(w), []).append(w)
print(by_length)

by_letter = defaultdict(list)
for w in words:
    by_letter[w[0]].append(w)
print(dict(by_letter))

  • d.get(key, default) reads a value that may be missing.
  • key in d lets you decide what to do before reading.
  • d.setdefault(key, default) inserts the default only when the key is missing, then returns the value stored under that key.
  • defaultdict(list) or defaultdict(int) fills in missing keys automatically.
  • try/except KeyError suits a missing key that is rare and should be handled in one place.

Square brackets are still the right choice when a key must be there. If it's missing, a loud KeyError points you straight at the real bug instead of letting a silent default hide it.

Quick reference: Python KeyError

4Python KeyError: syntax

d[key]                    # KeyError if key is missing
d.get(key)                # None if missing
d.get(key, default)       # default if missing
key in d                  # True / False
d.setdefault(key, [])     # add default if missing, return value
d.pop(key, None)          # remove without a KeyError

from collections import defaultdict
counts = defaultdict(int) # missing keys start at 0

5Python KeyError: run the example

Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.

Interactive example
orders = [
    {"id": 101, "customer": "Asha", "coupon": "SAVE10"},
    {"id": 102, "customer": "Ben"},
    {"id": 103, "customer": "Chen", "coupon": "FREESHIP"},
]

for order in orders:
    try:
        print(order["id"], "coupon:", order["coupon"])
    except KeyError as err:
        print(order["id"], "has no key", err)

for order in orders:
    coupon = order.get("coupon", "none")
    print(f"{order['customer']}: {coupon}")

print("Keys in order 102:", list(orders[1]))
Expected output101 coupon: SAVE10
102 has no key 'coupon'
103 coupon: FREESHIP
Asha: SAVE10
Ben: none
Chen: FREESHIP
Keys in order 102: ['id', 'customer']

7Python KeyError: how the example works

Hover or tap a step to highlight its lines in the example above.

  1. Line 1-5A list of three order dictionaries, like records loaded from a JSON file. Order 102 has no "coupon" key because it's an optional field.
  2. Line 7-9The first loop reads order["coupon"] with square brackets. That works for orders 101 and 103.
  3. Line 10-11For order 102 the lookup raises KeyError. The except block catches it, and err prints as the missing key: 'coupon'.
  4. Line 13-15The second loop uses get("coupon", "none"), which never raises: it returns the coupon when it exists and the default "none" when it doesn't.
  5. Line 17list(orders[1]) lists the keys a dictionary really has. It's the quickest way to see why a lookup failed.

8Python KeyError: common mistakes

The key's spelling or capitalisation doesn't match

✗ Wrong

stock = {"apples": 4, "pears": 0}
print(stock["Apples"])
KeyError: 'Apples'

✓ Right

stock = {"apples": 4, "pears": 0}
item = "Apples"
print(stock[item.lower()])

Keys are case-sensitive. Use the exact key, or store keys in lowercase and convert what you look up with .lower() (and .strip() for stray spaces).

Adding to a count before the key exists

✗ Wrong

votes = ["yes", "no", "yes"]
tally = {}
for v in votes:
    tally[v] += 1
KeyError: 'yes'

✓ Right

votes = ["yes", "no", "yes"]
tally = {}
for v in votes:
    tally[v] = tally.get(v, 0) + 1
print(tally)

tally[v] += 1 has to read tally[v] first, and the first time a vote appears there is nothing to read. Start from 0 with get(), or use defaultdict(int).

Looking up a number when the keys are strings

✗ Wrong

import json
medals = json.loads('{"1": "gold", "2": "silver"}')
print(medals[1])
KeyError: 1

✓ Right

import json
medals = json.loads('{"1": "gold", "2": "silver"}')
place = 1
print(medals[str(place)])

JSON object keys are always strings, so the key is "1", not the number 1. Notice the message shows 1 without quotes. Convert the number with str().

9Python KeyError: exercises

Write your answer, then press Check. The checks run in your browser.

1. Price with a default

Write code Easy

Write get_price(menu, item) that returns the price of item from the dictionary menu, or 0 if the item isn't on the menu. It must never raise a KeyError.

Your code
def get_price(menu, item):
    # return the price, or 0 if item is not in menu
    pass

menu = {"tea": 2.5, "cake": 4.0}
print(get_price(menu, "tea"))
print(get_price(menu, "pizza"))

2. Predict get() and setdefault()

Predict the output Medium

Read the code and type exactly what it will print. Then press Check to compare.

Read this code
stock = {"pen": 3, "ink": 0}
print(stock.get("ink", 5))
print(stock.get("pad", 5))
print("pad" in stock)
stock.setdefault("pad", 10)
stock.setdefault("pen", 99)
print(stock)

2 more exercises → 4 more examples

Finished this lesson?
Progress is saved in this browser — create a free account to keep it across devices.

Questions learners ask

How do I check if a key exists in a Python dictionary?

Use the in operator: if "email" in user: ... It returns True or False and never raises an error. Use not in for the opposite check. There is no need to call .keys(); key in d is the fastest and clearest way.

Should I use get() or try/except KeyError?

Use get(key, default) when a missing key is normal and a sensible default exists, like an optional coupon. Use try/except KeyError when a missing key is unusual and you want to handle it in one place. Use plain square brackets when the key must always be there, so a bug shows up immediately.

Why does my KeyError show a number, like KeyError: 0?

Python is showing the exact key it searched for: here the integer 0. Either the dictionary's keys are strings ("0"), which is always true for data loaded from JSON, or you treated a dictionary like a list and used a position. Print list(your_dict) to see the real keys.

Further reading

10Next lesson

Up nextPython IndexError: list index out of rangeAn IndexError happens when you ask a list, tuple or string for a position that doesn't exist, such as item 3 of a list …

Related:
Python DictionariesPython Exceptions: try, except, else and finallyPython IndexError: list index out of rangeWorking with JSON in Python

← Python TypeError: What It Means and How to Fix It · All Errors and Exceptions lessons · Practise in the IDE