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

При работе со словарями в Python вы часто сталкиваетесь с исключениями KeyError.

Словари – это встроенные структуры данных, состоящие из пар ключ-значение. Используя словари, вы можете искать значения по ключам, при этом поиск будет иметь постоянную временную сложность. А что будет, если вы запросите значение ключа, но такого ключа в словаре не окажется? В этом случае Python выдаст ошибку KeyError.

Есть несколько способов обработки исключений KeyError. Вы можете обрабатывать их явно или использовать некоторые методы для установки значений по умолчанию для отсутствующих ключей. В этой статье мы рассмотрим, как обрабатывать KeyError с помощью блоков try-except, словарного метода get() и defaultdict из модуля collections.

Давайте начнем.

1. Как обрабатывать исключения KeyError с помощью блоков try-except

Для начала давайте рассмотрим, когда возникают ошибки KeyError.

В Python исключение KeyError возникает, когда вы пытаетесь получить доступ к значению несуществующего ключа. Для примера возьмем словарь books:

books = {
	"1984": "George Orwell",
	"To Kill a Mockingbird": "Harper Lee",
	"The Great Gatsby": "F. Scott Fitzgerald"
}

В словаре books ключами являются названия книг, а значениями – имена авторов. Таким образом, вы можете найти автора книги, используя название в качестве ключа.

Теперь попробуем вывести на экран имя автора книги, которой нет в словаре:

print(books["Brave New World"])

Вы столкнетесь с исключением KeyError:

Traceback (most recent call last):
  File "/home/balapriya/keyerror/main.py", line 7, in <module>
	print(books["Brave New World"])
      	~~~~~^^^^^^^^^^^^^^^^^^^
KeyError: 'Brave New World'

Исключения KeyError можно обрабатывать явно, с помощью блоков try-except. Например:

try:
	value = dictionary[key]
except KeyError:
	value = default_value

Здесь мы помещаем блок кода, который может вызвать исключение, в блок try. В данном случае мы пытаемся получить доступ к значению, связанному с ключом. Если возникнет ошибка KeyError, мы обработаем ее в блоке except, присвоив значение по умолчанию.

Примечание редакции: больше об обработке ошибок читайте в статье “Как обрабатывать исключения в Python”.

А теперь давайте применим это для нашего словаря с книгами:

books = {
	"1984": "George Orwell",
	"To Kill a Mockingbird": "Harper Lee",
	"The Great Gatsby": "F. Scott Fitzgerald"
}

try:
    # Try to access the key "Brave New World"
	author = books["Brave New World"]  
    # Catch the KeyError if the key does not exist
except KeyError:  
	author = "Book not found"  

print(author) 

Мы снова пытаемся найти автора “Brave New World”. Но на этот раз ошибка KeyError триггерит блок except, и мы получаем не ошибку, а сообщение “Book not found”.

2. Обработка ошибок KeyError с помощью метода get()

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

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

value = dictionary.get(key, default_value)

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

Давайте теперь используем метод get() для словаря books. В качестве значения по умолчанию в вызове метода мы передадим “Book not found” («Книга не найдена»).

books = {
	"1984": "George Orwell",
	"To Kill a Mockingbird": "Harper Lee",
	"The Great Gatsby": "F. Scott Fitzgerald"
}

# Try to get the value for "Brave New World"
author = books.get("Brave New World", "Book not found")  
print(author)  

Вы должны получить следующий результат:

Output >>> Book not found

Примечание. Метод get() не изменяет исходный словарь. Если вы также хотите добавить в словарь отсутствующий ключ со значением по умолчанию, вы можете использовать метод setdefault() с синтаксисом dictionary.setdefault(key,default_value).

3. Как использовать defaultdict из модуля collections

Гораздо более чистым способом обработки ошибок KeyErrors является использование defaultdict из модуля collections Python. Defaultdict расширяет возможности встроенного словаря Python, позволяя вам предоставлять значение по умолчанию для ключей, которые не были заданы явно.

Конструктор defaultdict принимает в качестве аргумента фабричную функцию по умолчанию. Эта фабричная функция вызывается без аргументов, чтобы предоставить значение по умолчанию для несуществующего ключа.

Синтаксис создания defaultdict следующий:

from collections import defaultdict

# Syntax
defaultdict(default_factory)

Давайте создадим defaultdict из словаря books:

from collections import defaultdict

books = {
	"1984": "George Orwell",
	"To Kill a Mockingbird": "Harper Lee",
	"The Great Gatsby": "F. Scott Fitzgerald"
}

books_default = defaultdict(lambda: "Book not found",books)  
# Access the key "Brave New World"
author = books_default["Brave New World"]  
print(author) 

Для функции фабрики по умолчанию мы используем простую лямбда-функцию, которая возвращает строку “Book not found”. Эта функция вызывается при каждой попытке обращения к ключу, которого нет в словаре.

Выполнив этот код, мы должны получить сообщение о том, что книга не найдена.

Использование defaultdict может быть особенно полезным, когда вам нужно динамически обращаться ко многим ключам.

Заключение

Вот и все! Надеюсь, вы поняли, как обрабатывать исключения KeyError в Python. Давайте повторим:

  • Чтобы явно обработать KeyError, вы можете поместить код доступа к словарю в блок try и поймать KeyError в блоке except.
  • Для доступа к значению ключа с возможностью возврата значения по умолчанию, если ключ не существует, используйте метод get().
  • Вы можете инициализировать defaultdict из модуля collections с помощью фабричной функции, которая возвращает значение по умолчанию.

Перевод статьи «How to Handle KeyErrors in Python – with Code Examples».

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *