Метод get() в Python: как получить значение из словаря без KeyError

Метод get() в Python возвращает значение по ключу, а если ключа нет, отдаёт None или ваше значение по умолчанию вместо ошибки KeyError.

В статье примеры с values(), items(), setdefault() и pop(), доступ к вложенным словарям и шесть частых ошибок, от KeyError до dict_values, с реальным выводом кода.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 3119 статей автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3773 экспертных мнения Подписаться на Телеграм-канал
Обложка: Метод get() в Python: как получить значение из словаря без KeyError

Чтобы получить значение из словаря Python, вызовите метод get(): user.get("city"). Если ключ есть, метод вернёт его значение, если нет, вернёт None, и программа спокойно пойдёт дальше. Вторым аргументом можно задать свой ответ на случай, когда ключа нет: user.get("phone", "не указан").

Запись в квадратных скобках user["city"] отдаёт то же значение, но на отсутствующем ключе останавливает программу ошибкой KeyError. Все значения сразу достают методы values() и items(), а для вложенных словарей пригодится цепочка из get(). Остальные базовые конструкции языка собраны в шпаргалке по основным командам Python.

Как работает метод get()

Рой ищет нужную карточку в картотеке по ярлыку

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

user = {"name": "Анна", "city": "Казань", "age": 29}

print(user.get("city"))
print(user.get("phone"))
print(user.get("phone", "не указан"))

Результат:

Казань
None
не указан

В документации Python сказано прямо: раз значение по умолчанию равно None, метод никогда не вызывает KeyError. Сам словарь get() не меняет: после трёх вызовов в user по-прежнему три ключа, никакого "phone" там не появилось.

Как ведут себя разные способы обращения к ключу:

Запись Ключ есть Ключа нет
user["city"] значение ошибка KeyError
user.get("city") значение None
user.get("city", "нет данных") значение "нет данных"
user.setdefault("city", "") значение "", и ключ добавляется в словарь

Удобнее всего get() в счётчиках. Ноль по умолчанию избавляет от проверки, встречалось ли слово раньше. Список слов из настоящего текста даёт метод split(), он разобран в инструкции как превратить строку в список:

words = ["кот", "пёс", "кот", "ёж", "кот"]
counter = {}
for w in words:
    counter[w] = counter.get(w, 0) + 1
print(counter)

Результат:

{'кот': 3, 'пёс': 1, 'ёж': 1}

Квадратные скобки или get(): что выбрать

Квадратные скобки работают быстро и коротко, пока ключ на месте. Без него программа падает:

user = {"name": "Анна", "city": "Казань", "age": 29}

print(user["city"])
print(user["phone"])

Последняя строка ошибки:

Казань
KeyError: 'phone'

У нас в скриптах простое правило: обязательный ключ читаем скобками, необязательный через get().

Падение бывает полезным. Если ключ обязан быть в словаре (номер заказа, логин), ошибка сразу покажет строку, где данные пришли неполными. get() в такой ситуации молча вернёт None, и сломается что-то ниже по коду, где причину искать дольше.

  • Скобки d[key] берите, когда ключ обязательный и его отсутствие означает ошибку в программе.
  • d.get(key) подходит, когда ключа может не быть по нормальным причинам: необязательное поле анкеты, настройка, которую пользователь не менял, поле в ответе сервера.
  • Проверка key in d нужна, когда без ключа программа должна пойти по другой ветке, а не подставить заглушку.
user = {"name": "Анна", "city": "Казань", "age": 29}

if "phone" in user:
    print(user["phone"])
else:
    print("Телефона нет")

Результат:

Телефона нет

Такое условие из четырёх строк сворачивается в одну через тернарный оператор, но для выбора значения по умолчанию get() всё равно короче.

Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Как получить все значения, ключи и пары из словаря

Три коробки с ключами, значениями и парами на столе

Три метода отдают содержимое словаря целиком:

  • keys() возвращает ключи;
  • values() возвращает значения;
  • items() возвращает пары «ключ, значение».
prices = {"Python": 49000, "SQL": 18000, "Excel": 9000}

print(prices.keys())
print(prices.values())
print(prices.items())
print(sum(prices.values()))
print(list(prices.values()))

Результат:

dict_keys(['Python', 'SQL', 'Excel'])
dict_values([49000, 18000, 9000])
dict_items([('Python', 49000), ('SQL', 18000), ('Excel', 9000)])
76000
[49000, 18000, 9000]

Методы возвращают не списки, а представления словаря (view). По документации, представление динамическое: когда меняется словарь, меняется и оно. Ниже vals получили до того, как добавили Excel, а цена Excel в нём всё равно видна:

prices = {"Python": 49000, "SQL": 18000}
vals = prices.values()
prices["Excel"] = 9000
print(vals)

Результат:

dict_values([49000, 18000, 9000])

Чтобы взять значение по номеру или отсортировать значения, оберните представление в list(). Дальше с ним работают как с обычным списком, все приёмы собраны в статье про списки в Python.

Перебор пар через items()

Когда в цикле нужны и ключ, и значение, перебирайте items() и распаковывайте пару в две переменные:

prices = {"Python": 49000, "SQL": 18000, "Excel": 9000}

for course, price in prices.items():
    print(f"{course}: {price} ₽")

Результат:

Python: 49000 ₽
SQL: 18000 ₽
Excel: 9000 ₽

Порядок не случайный. С Python 3.7 словарь гарантированно хранит ключи в порядке добавления, это закреплено в описании типа dict. Если к паре нужен ещё и порядковый номер, добавьте функцию enumerate():

prices = {"Python": 49000, "SQL": 18000, "Excel": 9000}

for i, (course, price) in enumerate(prices.items(), 1):
    print(i, course, price)

Результат:

1 Python 49000
2 SQL 18000
3 Excel 9000
CheckroiCheckroiПодборка курсов для Python-разработчиков85 курсов • 33 школыСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Ещё три способа достать значение

setdefault(): получить и сразу записать

Метод setdefault() работает как get(), но при отсутствии ключа ещё и добавляет его в словарь со значением по умолчанию. Так описан в документации:

stats = {"Москва": 3}

print(stats.setdefault("Москва", 0))
print(stats.setdefault("Пермь", 0))
print(stats)

Результат:

3
0
{'Москва': 3, 'Пермь': 0}

Где это удобно: группировка. Список для курса создаётся при первой встрече, дальше в него добавляются имена.

students = [("Анна", "Python"), ("Олег", "SQL"), ("Ира", "Python")]
groups = {}
for name, course in students:
    groups.setdefault(course, []).append(name)
print(groups)

Результат:

{'Python': ['Анна', 'Ира'], 'SQL': ['Олег']}

pop(): забрать значение и удалить ключ

pop() возвращает значение и сразу убирает пару из словаря. Без второго аргумента на отсутствующем ключе он падает с KeyError, как скобки, а со вторым возвращает его:

order = {"id": 512, "status": "new", "promo": "AUTUMN"}

promo = order.pop("promo")
print(promo)
print(order)
print(order.pop("promo", None))

Результат:

AUTUMN
{'id': 512, 'status': 'new'}
None

У списков есть одноимённый метод, только он берёт элемент по номеру. Разница разобрана в инструкции как удалить элемент из списка.

try/except: когда без ключа нужна своя обработка

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

user = {"name": "Анна", "city": "Казань"}

try:
    phone = user["phone"]
except KeyError:
    phone = "не указан"
print(phone)

Результат:

не указан
CheckroiCheckroiПодборка курсов по Python569 курсов • 52 школыСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Как достать значение из вложенного словаря

Ответ сервера или файл JSON, прочитанный в Python, часто превращается в словарь словарей. Обращение response["user"]["profile"]["city"] упадёт на первом же пропавшем уровне. Безопасный вариант: цепочка get() с пустым словарём по умолчанию на каждом промежуточном шаге:

response = {"user": {"profile": {"city": "Пермь"}}}

print(response.get("user", {}).get("profile", {}).get("city"))
print(response.get("user", {}).get("settings", {}).get("theme", "светлая"))

Результат:

Пермь
светлая

Когда уровней больше трёх, цепочка перестаёт читаться. Тогда проще написать свою функцию, которая пройдёт путь по ключам и вернёт значение по умолчанию на первом же отсутствующем шаге:

def deep_get(data, *keys, default=None):
    for key in keys:
        if not isinstance(data, dict) or key not in data:
            return default
        data = data[key]
    return data

response = {"user": {"profile": {"city": "Пермь"}}}
print(deep_get(response, "user", "profile", "city"))
print(deep_get(response, "user", "orders", 0, default="заказов нет"))

Результат:

Пермь
заказов нет

Как обновить значения: update() и оператор |

Рой собирает две стопки карточек в одну

Достать значение мало, иногда его нужно заменить. update() меняет словарь на месте: перезаписывает совпавшие ключи и добавляет новые. Оператор | появился в Python 3.9 (PEP 584) и собирает новый словарь, а исходные не трогает. При совпадении ключей побеждает значение из правого словаря.

settings = {"theme": "светлая", "lang": "ru"}

settings.update({"theme": "тёмная", "font": 14})
print(settings)

defaults = {"theme": "светлая", "lang": "ru"}
custom = {"lang": "en"}
print(defaults | custom)

Результат:

{'theme': 'тёмная', 'lang': 'ru', 'font': 14}
{'theme': 'светлая', 'lang': 'en'}
CheckroiCheckroiПодборка курсов по Python464 курса • 49 школСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→ Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Частые ошибки и как их исправить

get() вернул None, хотя ключ есть

Значит, в словаре по этому ключу и лежит None. По ответу get() эти два случая не различить:

user = {"name": "Анна", "phone": None}

print(user.get("phone"))
print(user.get("email"))
print("phone" in user, "email" in user)

Результат:

None
None
True False

Решение: если важно, есть ли ключ вообще, проверяйте "phone" in user.

TypeError: ‘dict_values’ object is not subscriptable

Представление values() не поддерживает индексы. Первая строка ниже работает, вторая падает:

prices = {"Python": 49000, "SQL": 18000}

print(list(prices.values())[0])
print(prices.values()[0])

Результат:

49000
TypeError: 'dict_values' object is not subscriptable

Решение: сначала list(prices.values()), потом индекс.

Значение по умолчанию вычисляется, даже когда не нужно

Python считает аргументы до вызова метода. Функция в роли значения по умолчанию выполнится, даже если ключ найден:

def load_default():
    print("считаю значение по умолчанию")
    return 0

stats = {"visits": 10}
print(stats.get("visits", load_default()))

Результат:

считаю значение по умолчанию
10

Решение: дорогое значение (запрос к базе, чтение файла) считайте в ветке if key not in d, а в get() передавайте только готовые константы.

RuntimeError: dictionary changed size during iteration

Удалять ключи прямо в цикле по словарю нельзя:

prices = {"Python": 49000, "SQL": 18000, "Excel": 9000}

for course in prices:
    if prices[course] < 10000:
        del prices[course]

Результат:

RuntimeError: dictionary changed size during iteration

Решение: перебирайте копию ключей list(prices).

prices = {"Python": 49000, "SQL": 18000, "Excel": 9000}

for course in list(prices):
    if prices[course] < 10000:
        del prices[course]
print(prices)

Результат:

{'Python': 49000, 'SQL': 18000}

Ключ «1» и ключ 1 не совпадают

Строка "1" и число 1 для словаря разные ключи. Ошибка частая, когда ключ приходит из input() или из файла CSV строкой:

grades = {1: "отлично", 2: "хорошо"}

print(grades.get("1"))
print(grades.get(int("1")))

Результат:

None
отлично

Решение: приводите ключ к нужному типу до поиска. Как безопасно превратить ввод в число, разобрано в статье про int(input()) в Python.

AttributeError: ‘list’ object has no attribute ‘get’

JSON часто приходит списком словарей, а не одним словарём. У списка метода get() нет:

data = [{"title": "Python с нуля"}]
print(data.get("title"))

Результат:

AttributeError: 'list' object has no attribute 'get'

Решение: сначала возьмите элемент списка, data[0].get("title"), или переберите список циклом и вызывайте get() у каждого элемента.

Где освоить Python системно

Словари встречаются почти в каждой программе на Python: настройки, ответы сервера, подсчёты, группировки. Закрепить их проще всего на коротких упражнениях, например на 30 задачах для начинающих.

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

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Профессия «Python-разработчик»
Перейти на сайт курса
SkillboxSkillbox157 335 ₽5987 ₽/мес.10 месяцевОбзор курса
Fullstack-разработчик на Python
Перейти на сайт курса
НетологияНетология137 000 ₽7125 ₽/мес.21 месяцОбзор курса
ДО Профессия Python-разработчик
Перейти на сайт курса
GeekBrainsGeekBrains149 001 ₽3167 ₽/мес.10 месяцевОбзор курса
Автоматизированное тестирование на Python
Перейти на сайт курса
SkillboxSkillbox122 226 ₽4108 ₽/мес.9 месяцевОбзор курса
Профессия Python-разработчик
Перейти на сайт курса
SkillFactorySkillFactory140 040 ₽3890 ₽/мес.10 месяцевОбзор курса

Больше программ — в полном каталоге курсов по Python

Часто задаваемые вопросы

Что вернёт метод get(), если ключа в словаре нет?

Без второго аргумента get() вернёт None, со вторым вернёт его. Ошибки KeyError не будет, программа продолжит работу: user.get("phone", "не указан") даст строку «не указан».

Чем get() отличается от обращения в квадратных скобках?

Пока ключ есть, результат одинаковый. Без ключа запись d[key] падает с KeyError, а d.get(key) возвращает None или значение по умолчанию. Скобки удобны для обязательных ключей: ошибка сразу покажет, где данные неполные.

Как получить все значения словаря списком?

Вызовите values() и оберните результат в list(): list(prices.values()). Сам values() возвращает представление dict_values, а у него нет индексов, поэтому prices.values()[0] падает с TypeError.

Как найти ключ по значению в словаре Python?

Переберите пары через items() и отберите ключи с нужным значением: [course for course, price in prices.items() if price == 18000]. Получится список, потому что одно значение может стоять у нескольких ключей.

Меняет ли get() словарь?

Нет, get() только читает. Если отсутствующий ключ нужно сразу добавить, используйте setdefault(): он вернёт значение и запишет ключ со значением по умолчанию. Подробнее о методе в разделе «Ещё три способа достать значение».

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

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

Напишите, что думаете. Нам важно ваше мнение!