Какие структуры данных в Python являются изменяемыми, а какие — неизменяемыми?

Ответ

В Python структуры данных делятся на изменяемые (mutable) и неизменяемые (immutable). Это фундаментальное различие влияет на их поведение, использование в качестве ключей словарей и передачу в функции.

Изменяемые (Mutable) структуры данных

Определение: Могут быть изменены после создания. Это означает, что их содержимое можно модифицировать без создания нового объекта. Изменения происходят "на месте", и все ссылки на этот объект будут видеть обновленное состояние.

Примеры:

  • list (список)
  • dict (словарь)
  • set (множество)
  • bytearray
  • Пользовательские классы (по умолчанию)

Пример изменяемого списка:

my_list = [1, 2, 3]
print(f"До изменения: {my_list}, id: {id(my_list)}")
my_list[0] = 5  # Изменяем элемент
print(f"После изменения: {my_list}, id: {id(my_list)}") # id объекта не изменился

Неизменяемые (Immutable) структуры данных

Определение: Не могут быть изменены после создания. Любая операция, которая кажется изменением, на самом деле создает новый объект. Старый объект остается нетронутым.

Примеры:

  • int, float, bool (числа)
  • str (строка)
  • tuple (кортеж)
  • frozenset (неизменяемое множество)
  • bytes

Пример неизменяемого кортежа:

my_tuple = (1, 2, 3)
print(f"До попытки изменения: {my_tuple}, id: {id(my_tuple)}")
# my_tuple[0] = 5  # TypeError: 'tuple' object does not support item assignment

# Операция, которая кажется изменением, создает новый объект
new_tuple = my_tuple + (4,)
print(f"Новый кортеж: {new_tuple}, id: {id(new_tuple)}") # id объекта изменился

Значение и ключевое отличие

Изменяемость/неизменяемость имеет критическое значение для:

  1. Хешируемости: Только хешируемые объекты могут быть ключами словаря (dict) или элементами множества (set). Неизменяемые объекты (как int, str, tuple) по умолчанию хешируемы, так как их хеш-значение не меняется. Изменяемые объекты (как list, dict, set) не хешируемы, поскольку их хеш мог бы измениться после модификации, нарушая целостность хеш-таблицы.

    • Пример: list нельзя использовать как ключ словаря, так как он изменяем и не хешируем.
  2. Передачи аргументов в функции: Изменяемые объекты, переданные в функцию, могут быть изменены внутри функции, что повлияет на исходный объект вне функции. Неизменяемые объекты не могут быть изменены таким образом; любые "изменения" создадут локальную копию.