How can I fix the KeyError in Python?

I’m writing a Python program and when I execute it I see the KeyError message. How can I fix it?

The KeyError exception is an error that many programmers see when they start using Python dictionaries.

The following points are important to understand this error:

  • The meaning of KeyError Python
  • How to fix key errors
  • How to handle key errors

What does KeyError mean?

A KeyError is a way for Python to tell you that you are trying to access a key that doesn’t exist in a dictionary.

As an example create a file called keyerror.py:

  • create a dictionary that contains countries and their capitals.
  • print the capital of Italy.
  • then print the capital of France.
countries = {'Italy': 'Rome', 'Poland': 'Warsaw', 'UK': 'London'}

print(countries['Italy'])
print(countries['France'])

When you execute this code Python raises a KeyError exception:

Rome
Traceback (most recent call last):
  File "keyerror.py", line 3, in <module>
    print(countries['France'])
KeyError: 'France'

As you can see, the value of the first key in the dictionary (Italy) is printed correctly. But the KeyError occurs with the second print statement.

Python raises a KeyError when you attempt to access a key that doesn’t exist in a dictionary.

In this case, the key ‘France’ doesn’t exist in the countries dictionary.

Notice also how Python tells at which line of code the exception has occurred. This is very useful to find the cause of the error quickly when you have hundreds or thousands of lines of code to go through.

Core skill: When Python raises an exception a traceback is included. A traceback gives you all the details you need to understand the type of exception and to find what has caused it in your code. 

How do I fix a KeyError in Python?

There are two basic fixes for the key error if your program is simple:

  1. Avoid referencing a key that doesn’t exist in a dictionary
  2. Add the missing key to the dictionary

But those are not robust approaches and don’t prevent a similar error from occurring again.

Let’s look instead at the other two options:

First option

Tell Python not to return a KeyError if you try to access a key that doesn’t exist in the dictionary, but to return a default value instead.

Let’s say you want to return the default value ‘Unknown’ for any keys not present in the dictionary. Here is how you can do it using the dictionary get() method:

countries = {'Italy': 'Rome', 'Poland': 'Warsaw', 'UK': 'London'}
default = 'Unknown'

print(countries.get('Italy', default))
print(countries.get('France', default))

The output becomes:

Rome
Unknown

So, at least in this way, you have more control over the output returned by your program.

Second option

Verify if a key exists in a dictionary using the in operator that returns a boolean (True or False) based on the existence of that key in the dictionary.

In the example below we use the in operator together with an if-else statement to verify if a key exists before accessing its value:

countries = {'Italy': 'Rome', 'Poland': 'Warsaw', 'UK': 'London'}

if 'France' in countries:
    print("The capital of France is %" % countries['France'])
else:
    print("The capital of France is unknown")

Here is the output:

The capital of France is unknown

This is also a good option!

How do you handle a KeyError?

In the previous section, we introduced the dictionary method get() to return a default value if a key doesn’t exist in a dictionary.

But, what happens if you don’t pass the default value as a second argument to the get() method?

countries = {'Italy': 'Rome', 'Poland': 'Warsaw', 'UK': 'London'}

print(countries.get('Italy'))
print(countries.get('France'))

Do you know what the output is?

Rome
None

Interestingly this time Python doesn’t raise a KeyError exception because the get() method returns None if a key doesn’t exist in a dictionary.

This means that you can implement conditional logic in your code based on the value returned by the get() method. Here’s an example:

countries = {'Italy': 'Rome', 'Poland': 'Warsaw', 'UK': 'London'}
  
capital = countries.get('France')

if capital:
    print("The capital is %s" % capital)
else:
    print("The capital is unknown")

The output is:

The capital is unknown

A good way to avoid that exception.

Avoiding the KeyError with a for loop

The KeyError occurs when you try to access a key that doesn’t exist in a dictionary. This means that you can prevent a KeyError by making sure you only access keys that exist in the dictionary.

You can do that by using a for loop that goes through all the keys of the dictionary. This would ensure that you only refer to keys that are present in the dictionary.

Let’s have a look at one example:

countries = {'Italy': 'Rome', 'Poland': 'Warsaw', 'UK': 'London'}

for key in countries:
    print("The capital of %s is %s" % (key, countries[key]))

The output is:

The capital of Italy is Rome
The capital of Poland is Warsaw
The capital of UK is London

You can use a for loop to go through all the keys in a dictionary and ensure you don’t access keys not in the dictionary. This prevents the Python KeyError exception from occurring.

How can I handle the KeyError exception when it happens?

A generic approach you can use with any exceptions is the try-except block. This allows you to handle the exception in a clean way using the except block.

Here is how this applies to our example:

countries = {'Italy': 'Rome', 'Poland': 'Warsaw', 'UK': 'London'}
  
try:
    print('The capital of France is %s' % countries['France'])
except KeyError:
    print('The capital of France is unknown')

In this example, the except block is written specifically to handle the KeyError exception. We could have also used a generic exception by removing KeyError.

try:
    print('The capital of France is %s' % countries['France'])
except:
    print('The capital of France is unknown')

So, do we need to specify the exception type?

It can be handy if the try block could raise multiple types of exceptions and we want to handle each exception differently.

Leave a Comment