Ответ
В Python ключом словаря может быть любой хешируемый (hashable) объект. Хешируемость означает, что объект имеет неизменяемое значение хеша на протяжении всей его жизни и может быть сравнен с другими объектами.
На практике это означает:
- Можно использовать: Все неизменяемые встроенные типы.
int,float,decimal.Decimalstr,bytesbooltuple(но только если все его элементы также хешируемы).frozensetNone
- Нельзя использовать: Изменяемые (mutable) типы.
list,set,dict- Пользовательские классы по умолчанию хешируемы (по их
id), но это поведение можно изменить, определив методы__hash__и__eq__.
Примеры:
# Допустимые ключи
valid_dict = {
42: 'integer',
3.14: 'float',
'name': 'string',
('localhost', 8080): 'tuple as key', # Кортеж из хешируемых элементов
frozenset([1, 2, 3]): 'frozenset key',
None: 'None key'
}
# НЕДОПУСТИМЫЕ ключи вызовут TypeError: unhashable type
invalid_attempts = {
[1, 2]: 'list', # Список - изменяемый
{'key': 'val'}: 'dict', # Словарь - изменяемый
{1, 2}: 'set' # Множество - изменяемое
}
Это ограничение связано с внутренней реализацией словарей Python, которая использует хеш-таблицы для быстрого доступа. Изменяемый ключ мог бы изменить свой хеш после добавления в словарь, что сломало бы механизм поиска.