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