Python: работа со словарями и задание дефолтных значений

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

В Python collections.defaultdict автоматически присваивает значение по умолчанию несуществующим ключам, исключая необходимость ручной проверки или использования dict.get().

Python
Скопировать код
from collections import defaultdict

# defaultdict работает как товарищ, у которого всегда есть запасная ручка.
my_dict = defaultdict(int)
print(my_dict['нет_ключа'])  # Вывод: 0, и ошибки KeyError нет! 🎉

my_dict['есть_ключ'] = 10
print(my_dict['есть_ключ'])  # Что вы думаете? Вывод: 10. 🙌

defaultdict(int) немедленно предоставит вам инициализированный нулем объект int для любого несуществующего ключа. Это удобно и эффективно.

Кинга Идем в IT: пошаговый план для смены профессии

Эффективное управление отсутствующими ключами

Иногда необходимо обрабатывать отсутствие ключей так, чтобы вернуть альтернативное значение, а не сохранять отсутствующие ключи. В этом случае подходит dict.get(key, default):

Python
Скопировать код
my_dict = {'яблоко': 3, 'банан': 2}

# Проверяем наличие вишни. Если её нет, то возвращаем 0🍒
количество = my_dict.get('вишня', 0)
print(количество)  # 0

Если же вам нужно обеспечить инициализацию нескольких отсутствующих ключей, dict.setdefault(key, default) в этом поможет:

Python
Скопировать код
my_dict.setdefault('вишня', 0)
print(my_dict['вишня'])  # 0, теперь и вишня тоже в нашем "фруктовом корзине" 🍒

Если требуется установить значения по умолчанию для нескольких ключей, то метод dict.update() позволит объединить текущий словарь с другим, содержащим требуемые значения, при этом не затрагивая уже существующие ключи:

Python
Скопировать код
defaults = {'вишня': 0, 'ягода': 0}
my_dict.update({k: defaults[k] for k in defaults if k not in my_dict})

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

Python
Скопировать код
try:
    value = my_dict['груша']
except KeyError:
    value = 0  # Подготовка к изящноому "упадку" 🛡️

Глубинное изучение значений по умолчанию

defaultdict с методами

defaultdict позволяет использовать функцию для генерации нестандартных значений по умолчанию, что делает его поистине универсальным инструментом:

Python
Скопировать код
from collections import defaultdict

def default_factory():
    return 'значение по умолчанию'

умный_словарь = defaultdict(default_factory)
print(умный_словарь['несуществующий'])  # 'значение по умолчанию', даже если такого ключа нет!

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

Секрет setdefault

setdefault на первый взгляд кажется простым, однако он возвращает значение, что позволяет улучшить эффективность кода:

Python
Скопировать код
count = my_dict.setdefault('яблоко', 0)  # Подсчитываем
my_dict['яблоко'] = count + 1            # Обновляем. Всё это в одной строке! 🍏

Сравнение get и __getitem__

dict.get() и dict[key] могут показаться идентичными, однако они работают по-разному. get() никогда не вызывает ошибку и позволяет установить индивидуальное значение по умолчанию, тогда как __getitem__ (или dict[key]) в случае отсутствия ключа вызывает исключение KeyError.

Визуализация

Представьте себе словари Python как почтовое отделение, где письма (значения) доставляются по адресам (ключам). Если адреса не существует (нет такого ключа), на помощь приходит план "Вернуть отправителю" — это и есть значение по умолчанию.

Markdown
Скопировать код
Почтовое Отделение (📬): [Ключ 1, Ключ 2, Ключ 3]
Письмо для Ключа 2: ✉️ -> 📬[Ключ 2]
Что делать с письмом для Ключа 4?: ✉️ -> 🔙 Значение По Умолчанию

В коде это выглядит так:

Python
Скопировать код
почтовые_ящики.get('Ключ 4', 'Вернуть отправителю')

Даже при отсутствии ключа, значения не теряются — значение по умолчанию обеспечивает сохранность данных.

Markdown
Скопировать код
| Попытка  | Адрес существует? | Результат                |
| -------- | ------------------ | ------------------------ |
| Ключ 2   | Да                 | Доставлено 📬[Ключ 2]    |
| Ключ 4   | Нет                | Возвращено 🔙 как Значение По Умолчанию |

Таким образом, значение по умолчанию — это своеобразный гарант доставки без задержек и ошибок.

Управление значениями по умолчанию для словарей

Настройка с помощью __missing__

Создав подкласс dict, можно переопределить метод __missing__, контролируя таким образом поведение при обращении к отсутствующим ключам:

Python
Скопировать код
class SpecialDict(dict):
    def __missing__(self, key):
        return 'особое значение по умолчанию'

мой_особый_словарь = SpecialDict()
print(мой_особый_словарь['призрак'])  # 'особое значение по умолчанию', всё проходит без проблем!

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

Вопросы производительности

  • Если ключи в словаре в основном существуют, использование try/except предпочтительнее, поскольку опыт показывает, что исключения бывают редкими.
  • Если же ключи регулярно отсутствуют, лучше использовать get(), так как этот метод эффективно снижает затраты на обработку исключений.

Будьте осторожны!

  • Излишнее использование setdefault может внести лишние изменения в словарь. Оно не всегда является лучшим решением.
  • Операция update() может перезаписать существующие ключи, что в некоторых случаях нежелательно. Требует аккуратного использования.

Полезные материалы

  1. Документация Python по методу dict.get() — безопасный доступ к элементам словаря.
  2. Принцип работы defaultdict — документация по части модуля collections.
  3. Руководство по использованию defaultdict — правила работы с defaultdict.
  4. [Сравнение dict.get() и dict[key]](https://stackoverflow.com/questions/11041405/why-dict-getkey-instead-of-dictkey) — различия между двумя способами доступа к значениям словаря.
  5. Определение поведения для отсутствующих ключей с __missing__ — настройка поведения для несуществующих ключей.
  6. Основы словарей Python — ключевые особенности и методы словарей Python.