Как ответить
Ключом словаря в Python может быть любой хешируемый объект. По сути, объект считается хешируемым, если у него есть метод __hash__() (значение которого не меняется в течение жизни объекта) и он поддерживает сравнение через __eq__(). Если объект изменяемый, его хеш нестабилен, поэтому такие объекты не подходят — словарь не сможет надёжно хранить и находить записи.
Стандартные примеры рабочих ключей:
- Строки — самый частый вариант. Пример:
d['name'] = 'John'. - Числа (целые, с плавающей точкой, комплексные).
d[42] = 'answer'. - Кортежи, если все их элементы тоже хешируемые.
d[(1, 2)] = 'point'. - Frozenset — неизменяемый аналог множества.
- None — технически
Noneхешируется, можно использовать как ключ, хотя на практике редко. - Пользовательские классы — если в них правильно реализованы
__hash__и__eq__.
Нельзя использовать в качестве ключей:
- Списки, словари, обычные множества и другие изменяемые коллекции.
- Кортеж, содержащий изменяемый объект — например, кортеж со списком вызовет ошибку.
Вот небольшой пример, демонстрирующий верные и неверные ключи:
d = {}
# Рабочие ключи
d['key'] = 1
d[10] = 2
d[(1, 2)] = 3
d[frozenset({1, 2})] = 4
# Ошибка — список изменяем
d[[1, 2]] = 5 # TypeError: unhashable type: 'list'
# Ошибка — кортеж содержит список
d[(1, [2, 3])] = 6 # TypeError: unhashable type: 'list'На собеседовании стоит упомянуть, что хешируемость — основное ограничение. Также полезно отметить, что строки и целые числа — самые эффективные ключи: у них быстрый хеш и простое сравнение. Если использовать кортеж как координату точки — хороший кейс. Если же кортеж большой и содержит много вложенных структур, скорость доступа может снизиться из-за вычисления хеша.