Чем отличаются неизменяемые и хэшируемые типы данных в Python?

Ответ

Неизменяемый (immutable) тип — это объект, состояние которого нельзя изменить после его создания. Примеры: int, str, tuple, frozenset.

Хэшируемый (hashable) тип — это объект, который имеет хэш-значение, не меняющееся на протяжении его жизни. Такие объекты могут быть ключами в словарях (dict) и элементами множеств (set).

Ключевое различие:

Все хэшируемые объекты неизменяемы, но не все неизменяемые объекты хэшируемы.

Это связано с тем, что хэш-значение объекта вычисляется на основе его содержимого. Если бы содержимое могло измениться (т.е. объект был бы изменяемым), его хэш тоже бы изменился, что нарушило бы работу словарей и множеств.

Классический пример нехэшируемого, но неизменяемого объекта — кортеж, содержащий изменяемый элемент (например, список).

Пример:

# Строка - неизменяемая и хэшируемая
my_dict = {"hello": 1}
print(hash("hello"))  # Работает

# Кортеж с неизменяемыми элементами - неизменяемый и хэшируемый
tuple_1 = (1, 2, 3)
my_set = {tuple_1}
print(hash(tuple_1))  # Работает

# Кортеж с изменяемым элементом (списком) - неизменяемый, но НЕ хэшируемый
tuple_2 = (1, [2, 3])
try:
    hash(tuple_2)
except TypeError as e:
    print(e)  # Вывод: unhashable type: 'list'