Как исправить ошибку KeyError в Python?

Я пишу программу на Python, и когда я ее выполняю, я вижу сообщение KeyError. Как я могу это исправить?

Исключение KeyError — это ошибка, которую видят многие программисты, когда начинают использовать словари Python.

Для понимания этой ошибки важны следующие моменты:

  • Значение KeyError Python
  • Как исправить ключевые ошибки
  • Как справиться с ключевыми ошибками

Что означает KeyError?

KeyError — это способ Python сообщить вам, что вы пытаетесь получить доступ к ключу, которого нет в словаре.

В качестве примера создайте файл с именем keyerror.py:

  • создать словарь, содержащий страны и их столицы.
  • напечатайте столицу Италии.
  • затем напечатайте столицу Франции.
countries = {'Italy': 'Rome', 'Poland': 'Warsaw', 'UK': 'London'}

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

Когда вы выполняете этот код, Python вызывает исключение KeyError:

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

Как видите, значение первого ключа в словаре (Италия) печатается правильно. Но KeyError возникает со вторым оператором печати.

Python выдает ошибку KeyError, когда вы пытаетесь получить доступ к ключу, которого нет в словаре.

В этом случае ключ «Франция» не существует в countriesсловаре.

Обратите также внимание на то, как Python сообщает, в какой строке кода произошло исключение. Это очень полезно для быстрого поиска причины ошибки, когда вам нужно просмотреть сотни или тысячи строк кода.

Основной навык: когда Python вызывает исключение, включается обратная трассировка. Обратная трассировка дает вам всю информацию, необходимую для понимания типа исключения и того, что его вызвало в вашем коде.

Как исправить ошибку KeyError в Python?

Если ваша программа проста, есть два основных исправления ошибки ключа:

  1. Избегайте ссылки на ключ, которого нет в словаре.
  2. Добавить недостающий ключ в словарь

Но это ненадежные подходы и не предотвращают повторение подобной ошибки.

Давайте вместо этого рассмотрим два других варианта:

Первый вариант

Скажите Python, чтобы он не возвращал KeyError, если вы пытаетесь получить доступ к ключу, которого нет в словаре, а вместо этого возвращал значение по умолчанию.

Допустим, вы хотите вернуть значение по умолчанию «Неизвестно» для всех ключей, отсутствующих в словаре. Вот как это можно сделать, используя метод словаря get():

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

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

Результат становится:

Rome
Unknown

Таким образом, по крайней мере, таким образом у вас будет больше контроля над выводом, возвращаемым вашей программой.

Второй вариант

Проверьте, существует ли ключ в словаре, с помощью оператора in, который возвращает логическое значение (истина или ложь) в зависимости от существования этого ключа в словаре.

В приведенном ниже примере мы используем оператор in вместе с оператором if-else, чтобы проверить, существует ли ключ, прежде чем получить доступ к его значению:

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")

Вот результат:

The capital of France is unknown

Это тоже хороший вариант!

Как вы справляетесь с KeyError?

В предыдущем разделе мы представили словарный метод get(), который возвращает значение по умолчанию, если ключ не существует в словаре.

Но что произойдет, если вы не передадите значение по умолчанию в качестве второго аргумента метода get()?

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

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

Знаете ли вы, какой выход?

Rome
None

Интересно, что на этот раз Python не вызывает исключение KeyError, поскольку метод get() возвращает None, если ключ не существует в словаре.

Это означает, что вы можете реализовать условную логику в своем коде на основе значения, возвращаемого методом get(). Вот пример:

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 capital is unknown

Хороший способ избежать этого исключения.

Как избежать ошибки KeyError с помощью цикла for

Ошибка KeyError возникает, когда вы пытаетесь получить доступ к ключу, которого нет в словаре. Это означает, что вы можете предотвратить ошибку KeyError, обеспечив доступ только к ключам, существующим в словаре.

Вы можете сделать это, используя цикл for, который проходит по всем ключам словаря. Это гарантирует, что вы ссылаетесь только на ключи, которые присутствуют в словаре.

Давайте посмотрим на один пример:

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

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

Результат:

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

Вы можете использовать цикл for, чтобы просмотреть все ключи в словаре и гарантировать, что вы не получите доступ к ключам, которых нет в словаре. Это предотвращает возникновение исключения Python KeyError.

Как я могу обработать исключение KeyError, когда оно произойдет?

Общий подход, который можно использовать с любыми исключениями, — это блок try-кроме. Это позволяет вам обрабатывать исключение простым способом, используя блок исключений.

Вот как это применимо к нашему примеру:

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')

В этом примере блок исключений написан специально для обработки исключения KeyError. Мы также могли бы использовать общее исключение, удалив KeyError.

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

Итак, нужно ли нам указывать тип исключения?

Это может быть удобно, если блок try может вызывать несколько типов исключений, и мы хотим обрабатывать каждое исключение по-разному.