Ответ
Словари в Python (dict) реализованы на основе хеш-таблиц для обеспечения очень быстрого доступа к элементам (в среднем O(1)). Работа хеш-таблицы требует, чтобы ключ был хэшируемым.
Хэшируемый объект должен удовлетворять двум условиям:
- Иметь метод
__hash__(), который возвращает одно и то же целое число (хеш) на протяжении всей жизни объекта. - Иметь метод
__eq__()для сравнения с другими объектами. Еслиa == b, то обязательно должно выполнятьсяhash(a) == hash(b).
Изменяемые (mutable) объекты, такие как списки (list) или другие словари (dict), не могут быть ключами. Если бы значение такого объекта изменилось после добавления в словарь, его хеш также бы изменился, и объект стало бы невозможно найти.
Пример:
# Корректно: кортеж (tuple) является неизменяемым и хэшируемым
valid_key = (1, 2)
data = {valid_key: "value"}
print(data[(1, 2)]) # Вывод: value
# Ошибка: список (list) является изменяемым и нехэшируемым
invalid_key = [1, 2]
try:
data = {invalid_key: "value"}
except TypeError as e:
print(e) # Вывод: unhashable type: 'list' Ответ 18+ 🔞
А, слушай, вот тебе про словари в Питоне, это вообще отдельная песня, блядь. Они там внутри устроены на хеш-таблицах, чтобы всё летало как угорелое, в среднем за O(1). Но тут, сука, есть один важный нюанс, который всех новичков накрывает медным тазом!
Чтобы ключ в словарь воткнуть, он должен быть хэшируемым. А что это значит, спросишь ты? А значит вот что, пизда с ушами:
- У объекта должен быть метод
__hash__(), который, как клятва верности, возвращает одно и то же число на протяжении всей его гребаной жизни. - Должен быть метод
__eq__()для сравнения. И главное правило, ёпта: еслиa == b, то иhash(a)обязан быть равенhash(b). Иначе пиздец и бардак.
И вот тут-то собака и зарыта! Объекты изменяемые, как твои планы на выходные, — списки (list) или другие словари — ключами быть не могут. Представь, взял ты список, засунул его как ключ, а потом взял и изменил его содержимое. Его хеш, сука, поменяется! И как его потом в этой хеш-таблице найти? Да никак, он там потеряется нахуй, как иголка в стоге сена после запоя.
Смотри, пример, чтобы совсем понятно стало:
# Всё чётко: кортеж (tuple) — неизменяемый и хэшируемый, как скала.
valid_key = (1, 2)
data = {valid_key: "value"}
print(data[(1, 2)]) # Выведет: value
# А вот тут будет пиздец и TypeError: список — изменяемый, нехэшируемый.
invalid_key = [1, 2]
try:
data = {invalid_key: "value"}
except TypeError as e:
print(e) # Выведет: unhashable type: 'list'
Вот и весь сказ, блядь. Запомни раз и навсегда: в ключи — только неизменяемое барахло. А то будешь как Герасим, который Муму утопил, только тут ты сам себе программу утопишь, и совесть потом ебать будет.