Ответ
В 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 объекта изменился
Значение и ключевое отличие
Изменяемость/неизменяемость имеет критическое значение для:
-
Хешируемости: Только хешируемые объекты могут быть ключами словаря (
dict) или элементами множества (set). Неизменяемые объекты (какint,str,tuple) по умолчанию хешируемы, так как их хеш-значение не меняется. Изменяемые объекты (какlist,dict,set) не хешируемы, поскольку их хеш мог бы измениться после модификации, нарушая целостность хеш-таблицы.- Пример:
listнельзя использовать как ключ словаря, так как он изменяем и не хешируем.
- Пример:
-
Передачи аргументов в функции: Изменяемые объекты, переданные в функцию, могут быть изменены внутри функции, что повлияет на исходный объект вне функции. Неизменяемые объекты не могут быть изменены таким образом; любые "изменения" создадут локальную копию.
Ответ 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 уже другой, пиздец!
И вот эта ихняя изменяемость — это не просто так, для красоты. Это, блядь, фундаментально!
-
Ключи в словарях. Ты ж не можешь взять мешок с дырявым дном и использовать его как сейф? Вот и изменяемый объект (
list,dict,set) не может быть ключом словаря, потому что он, сука, может измениться, и хеш его полетит к чёртовой матери. А неизменяемые (int,str,tuple) — они как скала, на них можно положиться. -
Передача в функции. Отправляешь изменяемый список в функцию — там его могут так изнасиловать, что он вернётся совсем другим, и все, кто на него ссылался, охуеют. А неизменяемый кортеж отправишь — хоть обоссысь внутри функции, снаружи всё останется как было, чисто и неприкосновенно.
Вот так вот, вся магия в этом. Один объект — как пластилин, лепи что хочешь. Другой — как гранитная плита, только новую заказывать.