Basics Intermediate Advanced
aialgorithmsapibest-practicescareercommunitydatabasesdata-sciencedata-structuresdata-vizdevopsdjangodockereditorsflaskfront-endgamedevguimachine-learningnewsnumpyprojectspythonstdlibtestingtoolsweb-devweb-scraping
Recommended Course

KeyError Exceptions in Python and How to Handle Them
10m · 5 lessons

Python KeyError Exceptions and How to Handle Them
Table of Contents
Recommended Course
Python’sKeyError exception is a common exception encountered by beginners. Knowing why aKeyError can be raised and some solutions to prevent it from stopping your program are essential steps to improving as a Python programmer.
By the end of this tutorial, you’ll know:
- What a Python
KeyErrorusually means - Where else you might see a
KeyErrorin the standard library - How to handle a
KeyErrorwhen you see it
Free Bonus:Click here to get our free Python Cheat Sheet that shows you the basics of Python 3, like working with data types, dictionaries, lists, and Python functions.
What a PythonKeyError Usually Means
A PythonKeyErrorexception is what is raised when you try to access a key that isn’t in adictionary (dict).
Python’sofficial documentation says that theKeyError is raised when a mapping key is accessed and isn’t found in the mapping. A mapping is a data structure that maps one set of values to another. The most common mapping in Python is the dictionary.
The PythonKeyError is a type ofLookupError exception and denotes that there was an issue retrieving the key you were looking for. When you see aKeyError, the semantic meaning is that the key being looked for could not be found.
In the example below, you can see a dictionary (ages) defined with the ages of three people. When you try to access a key that is not in the dictionary, aKeyError is raised:
>>>ages={'Jim':30,'Pam':28,'Kevin':33}>>>ages['Michael']Traceback (most recent call last): File"<stdin>", line1, in<module>KeyError:'Michael'Here, attempting to access the key'Michael' in theages dictionary results in aKeyError being raised. At the bottom of the traceback, you get the relevant information:
- The fact that a
KeyErrorwas raised - The key that couldn’t be found, which was
'Michael'
The second-to-last line tells you which line raised the exception. This information is more helpful when you execute Python code from a file.
Note: When an exception is raised in Python, it is done with atraceback. The traceback gives you all the relevant information to be able to determine why the exception was raised and what caused it.
Learning how to read a Python traceback and understanding what it is telling you is crucial to improving as a Python programmer. To learn more on Python tracebacks, check outUnderstanding the Python Traceback
In the program below, you can see theages dictionary defined again. This time, you will be prompted to provide the name of the person to retrieve the age for:
1# ages.py 2 3ages={'Jim':30,'Pam':28,'Kevin':33} 4person=input('Get age for: ') 5print(f'{person} is{ages[person]} years old.')This code will take the name that you provide at the prompt and attempt to retrieve the age for that person. Whatever you type in at the prompt will be used as the key to theages dictionary, on line 4.
Repeating the failed example from above, we get anothertraceback, this time with information about the line in the file that theKeyError is raised from:
$pythonages.pyGet age for: MichaelTraceback (most recent call last):File "ages.py", line 4, in <module> print(f'{person} is {ages[person]} years old.')KeyError: 'Michael'The program fails when you give a key that is not in the dictionary. Here, the traceback’s last few lines point to the problem.File "ages.py", line 4, in <module> tells you which line of which file raised the resultingKeyError exception. Then you are shown that line. Finally, theKeyError exception provides the missing key.
So you can see that theKeyError traceback’s final line doesn’t give you enough information on its own, but the lines before it can get you a lot closer to understanding what went wrong.
Note: Like the example above, most of the other examples in this tutorial make use off-strings, which were introduced in Python 3.6.
Where Else You Might See a PythonKeyError in the Standard Library
The large majority of the time, a PythonKeyError is raised because a key is not found in a dictionary or a dictionary subclass (such asos.environ).
In rare cases, you may also see it raised in other places in Python’s Standard Library, such as in thezipfile module, if an item is not found in a ZIP archive. However, these places keep the same semantic meaning of the PythonKeyError, which is not finding the key requested.
In the following example, you can see using thezipfile.ZipFile class to extract information about a ZIP archive using.getinfo():
>>>fromzipfileimportZipFile>>>zip_file=ZipFile('the_zip_file.zip')>>>zip_file.getinfo('something')Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/path/to/python/installation/zipfile.py", line 1304, in getinfo 'There is no item named %r in the archive' % name)KeyError:"There is no item named 'something' in the archive"This doesn’t really look like a dictionary key lookup. Instead, it is a call tozipfile.ZipFile.getinfo() that raises the exception.
The traceback also looks a little different with a little more information given than just the missing key:KeyError: "There is no item named 'something' in the archive".
The final thing to note here is that the line that raised theKeyError isn’t in your code. It is in thezipfile code, but previous lines of the traceback indicate which lines in your code caused the problem.
When You Need to Raise a PythonKeyError in Your Own Code
There may be times when it makes sense foryou to raise a PythonKeyError exception in your own code. This can be done by using theraisekeyword and calling theKeyError exception:
raiseKeyError(message)Usually, themessage would be the missing key. However, as in the case of thezipfile package, you could opt to give a bit more information to help the next developer better understand what went wrong.
Note: If you’d like to take a deep dive into usingraise, then check outPython’sraise: Effectively Raising Exceptions in Your Code.
If you decide to raise a PythonKeyError in your own code, just make sure that your use case matches the semantic meaning behind the exception. It should denote that the key being looked for could not be found.
How to Handle a PythonKeyError When You See It
When you encounter aKeyError, there are a few standard ways to handle it. Depending on your use case, some of these solutions might be better than others. The ultimate goal is to stop unexpectedKeyError exceptions from being raised.
The Usual Solution:.get()
If theKeyError is raised from a failed dictionary key lookup in your own code, you can use.get() to return either the value found at the specified key or a default value.
Much like the age retrieval example from before, the following example shows a better way to get the age from the dictionary using the key provided at the prompt:
1# ages.py 2 3ages={'Jim':30,'Pam':28,'Kevin':33} 4person=input('Get age for: ') 5age=ages.get(person) 6 7ifage: 8print(f'{person} is{age} years old.') 9else:10print(f"{person}'s age is unknown.")Here, line 5 shows how you can get the age value fromages using.get(). This will result in theagevariable having the age value found in the dictionary for the key provided or a default value,None in this case.
This time, you will not get aKeyError exception raised because of the use of the safer.get() method to get the age rather than attempting to access the key directly:
$pythonages.pyGet age for: MichaelMichael's age is unknown.In the example execution above, theKeyError is no longer raised when a bad key is provided. The key'Michael' is not found in the dictionary, but by using.get(), we get aNone returned rather than a raisedKeyError.
Theage variable will either have the person’s age found in the dictionary or the default value (None by default). You can also specify a different default value in the.get() call by passing a second argument.
This is line 5 from the example above with a different default age specified using.get():
age=ages.get(person,0)Here, instead of'Michael' returningNone, it would return0 because the key isn’t found, and the default value to return is now0.
The Rare Solution: Checking for Keys
There are times when you need to determine the existence of a key in a dictionary. In these cases, using.get() might not give you the correct information. Getting aNone returned from a call to.get() could mean that the key wasn’t found or that the value found at the key in the dictionary is actuallyNone.
With a dictionary or dictionary-like object, you can use thein operator to determine whether a key is in the mapping. This operator will return aBoolean (True orFalse) value indicating whether the key is found in the dictionary.
In this example, you are getting aresponse dictionary fromcalling an API. This response might have anerror key value defined in the response, which would indicate that the response is in an error state:
1# parse_api_response.py 2... 3# Assuming you got a `response` from calling an API that might 4# have an error key in the `response` if something went wrong 5 6if'error'inresponse: 7...# Parse the error state 8else: 9...# Parse the success stateHere, there is a difference in checking to see if theerror key exists in theresponse and getting a default value from the key. This is a rare case where what you are actually looking for is if the key is in the dictionary and not what the value at that key is.
The General Solution:tryexcept
As with any exception, you can always use thetryexcept block to isolate the potential exception-raising code and provide a backup solution.
You can use thetryexcept block in a similar example as before, but this time providing a default message to be printed should aKeyError be raised in the normal case:
1# ages.py 2 3ages={'Jim':30,'Pam':28,'Kevin':33} 4person=input('Get age for: ') 5 6try: 7print(f'{person} is{ages[person]} years old.') 8exceptKeyError: 9print(f"{person}'s age is unknown.")Here, you can see the normal case in thetry block of printing the person’s name and age. The backup case is in theexcept block, where if aKeyError is raised in the normal case, then the backup case is to print a different message.
Thetryexcept block solution is also a great solution for other places that might not support.get() or thein operator. It is also the best solution if theKeyError is being raised from another person’s code.
Here is an example using thezipfile package again. This time, thetryexcept block gives us a way to stop theKeyError exception from stopping the program:
>>>fromzipfileimportZipFile>>>zip=ZipFile('the_zip_file.zip')>>>try:...zip.getinfo('something')...exceptKeyError:...print('Can not find "something"')...Can not find "something"Since theZipFile class does not provide.get(), like the dictionary does, you need to use thetryexcept solution. In this example, you don’t have to know ahead of time what values are valid to pass to.getinfo().
Conclusion
You now know some common places where Python’sKeyError exception could be raised and some great solutions you could use to prevent them from stopping your program.
Now, the next time you see aKeyError raised, you will know that it is probably just a bad dictionary key lookup. You will also be able to find all the information you need to determine where the error is coming from by looking at the last few lines of the traceback.
If the problem is a dictionary key lookup in your own code, then you can switch from accessing the key directly on the dictionary to using the safer.get() method with a default return value. If the problem isn’t coming from your own code, then using thetryexcept block is your best bet for controlling your code’s flow.
Exceptions don’t have to be scary. Once you know how to understand the information provided to you in their tracebacks and the root cause of the exception, then you can use these solutions to make your programs flow more predictably.
Recommended Course
🐍 Python Tricks 💌
Get a short & sweetPython Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

AboutChad Hansen
Chad is an avid Pythonista and does web development with Django fulltime. Chad lives in Utah with his wife and six kids.
» More about ChadMasterReal-World Python Skills With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:
MasterReal-World Python Skills
With Unlimited Access to Real Python
Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:
What Do You Think?
What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.
Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students.Get tips for asking good questions andget answers to common questions in our support portal.
Looking for a real-time conversation? Visit theReal Python Community Chat or join the next“Office Hours” Live Q&A Session. Happy Pythoning!
Keep Learning
Related Courses:
Related Tutorials:
Keep reading Real Python by creating a free account or signing in:
Already have an account?Sign-In




