← Назад к вопросам
Расскажи про изменяемые и неизменяемые типы данных
1.0 Junior🔥 191 комментариев
#SQL и базы данных
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Определение
Неизменяемые (Immutable) типы — объекты, которые не могут быть изменены после создания. Любое "изменение" создаёт новый объект.
Изменяемые (Mutable) типы — объекты, которые можно изменять на месте, без создания новых объектов.
Основные типы в Python
Неизменяемые:
int,float,complex(числа)str(строки)tuple(кортежи)frozenset(неизменяемое множество)bytes(байты)None,bool(синглтоны)
Изменяемые:
list(списки)dict(словари)set(множества)bytearray(массив байтов)
Примеры и различия
Неизменяемые типы
# Строки (immutable)
s = "hello"
# s[0] = 'H' # TypeError! Нельзя изменить
# "Изменение" создаёт новую строку
s = "hello"
s_new = s.upper() # Новый объект
print(s) # hello (исходная не изменилась)
print(s_new) # HELLO
# Кортежи (immutable)
t = (1, 2, 3)
# t[0] = 5 # TypeError! Нельзя изменить
t_new = t + (4,) # Новый кортеж
Изменяемые типы
# Списки (mutable)
lst = [1, 2, 3]
lst[0] = 99 # Можно изменить на месте
print(lst) # [99, 2, 3]
lst_id = id(lst)
lst.append(4) # Тот же объект в памяти
print(id(lst) == lst_id) # True
# Словари (mutable)
d = {"a": 1, "b": 2}
d["a"] = 100 # Изменение на месте
Опасность: Shared References (Ловушка!)
# Список в функции
original = [1, 2, 3]
copy = original # Не копирование, а указатель!
copy.append(4)
print(original) # [1, 2, 3, 4] — ИЗМЕНИЛСЯ!
# Правильное копирование
copy_correct = original.copy()
copy_correct.append(5)
print(original) # [1, 2, 3, 4] — не изменился
Проблема с изменяемыми аргументами
# Классическая ошибка!
def add_element(lst=[]): # Mutable default argument!
lst.append(1)
return lst
print(add_element()) # [1]
print(add_element()) # [1, 1] — список переиспользуется!
# Правильно:
def add_element(lst=None):
if lst is None:
lst = []
lst.append(1)
return lst
Практические следствия
Производительность
# Неизменяемые типы медленнее при "изменении"
s = "a"
for i in range(1000):
s = s + "b" # Каждый раз новая строка — O(n²)!
# Для строк лучше использовать join()
result = "".join("b" for _ in range(1000)) # O(n)
Использование в словарях
# Словари требуют hashable ключей (неизменяемые)
d = {}
d[(1, 2)] = "tuple key works" # tuple — hashable
# d[[1, 2]] = "list key" # TypeError!
# Множества требуют hashable элементов
s = {(1, 2), (3, 4)} # tuple работает
# s = {[1, 2]} # TypeError!
Многопоточность
# Неизменяемые типы безопаснее в многопоточности
tuple_data = (1, 2, 3) # Потоки не испортят это
# Проблема с изменяемым типом (без lock)
lst = []
# Может возникнуть race condition при параллельном доступе
Копирование
import copy
original = [[1, 2], [3, 4]]
# Поверхностное копирование (shallow copy)
shallow = original.copy()
shallow[0][0] = 99
print(original) # [[99, 2], [3, 4]] — изменился!
# Глубокое копирование (deep copy)
deep = copy.deepcopy(original)
deep[0][0] = 99
print(original) # [[1, 2], [3, 4]] — не изменился
Таблица сравнения
| Тип | Изменяемость | Hashable | Использование |
|---|---|---|---|
| int, float, str | Нет | Да | Числовые данные, тексты |
| tuple | Нет | Да | Ключи словарей, множества |
| list | Да | Нет | Изменяемые последовательности |
| dict | Да | Нет | Ключ-значение |
| set | Да | Нет | Уникальные элементы |
Итог
- Используй неизменяемые типы для ключей словарей, элементов множеств, параметров функций
- Используй изменяемые типы для коллекций, которые часто меняются
- Помни про shared references — присвоение копирует ссылку, не данные
- Для многопоточности неизменяемые типы безопаснее