Какие структуры данных в 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. Передачи аргументов в функции: Изменяемые объекты, переданные в функцию, могут быть изменены внутри функции, что повлияет на исходный объект вне функции. Неизменяемые объекты не могут быть изменены таким образом; любые "изменения" создадут локальную копию.

Ответ 18+ 🔞

Ну ты представляешь, в Питоне есть такие типы данных, которые как жена после ссоры — их можно переубедить, подкрутить, и они изменятся. А есть другие — как бабушкин характер, нихуя не сдвинешь, только новый создашь.

Вот смотри, есть изменяемые (mutable), как список. Это как твой холодильник — залез, переставил банки, добавил пива, а холодильник-то тот же самый, блядь, стоит.

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) — это как татуха на жопе. Захотел исправить «Люба» на «Людмила» — нихуя, только новую набивать, поверх старой не получится.

my_tuple = (1, 2, 3)
print(f"До: {my_tuple}, id: {id(my_tuple)}")
# my_tuple[0] = 5  # Ошибка! Кортеж не перепишешь, ёпта!
new_tuple = my_tuple + (4,)  # Создаёшь новый, как ребёнка от второго брака
print(f"Новый: {new_tuple}, id: {id(new_tuple)}") # id уже другой, пиздец!

И вот эта ихняя изменяемость — это не просто так, для красоты. Это, блядь, фундаментально!

  1. Ключи в словарях. Ты ж не можешь взять мешок с дырявым дном и использовать его как сейф? Вот и изменяемый объект (list, dict, set) не может быть ключом словаря, потому что он, сука, может измениться, и хеш его полетит к чёртовой матери. А неизменяемые (int, str, tuple) — они как скала, на них можно положиться.

  2. Передача в функции. Отправляешь изменяемый список в функцию — там его могут так изнасиловать, что он вернётся совсем другим, и все, кто на него ссылался, охуеют. А неизменяемый кортеж отправишь — хоть обоссысь внутри функции, снаружи всё останется как было, чисто и неприкосновенно.

Вот так вот, вся магия в этом. Один объект — как пластилин, лепи что хочешь. Другой — как гранитная плита, только новую заказывать.