← Назад к вопросам

Что такое изменяемые структуры данных?

1.3 Junior🔥 221 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

Изменяемые (mutable) структуры данных — это объекты, которые можно изменять после создания, не создавая новый объект. В отличие от неизменяемых (immutable), которые нельзя менять.

Основные изменяемые типы в Python

# 1. LIST — изменяемый список
my_list = [1, 2, 3]
my_list[0] = 99      # Изменяем элемент
my_list.append(4)    # Добавляем элемент
print(id(my_list))   # id остаётся ТЕМ ЖЕ

# 2. DICT — изменяемый словарь
my_dict = {"a": 1, "b": 2}
my_dict["a"] = 999   # Изменяем значение
my_dict["c"] = 3     # Добавляем новый ключ
print(id(my_dict))   # id остаётся ТЕМ ЖЕ

# 3. SET — изменяемое множество
my_set = {1, 2, 3}
my_set.add(4)        # Добавляем элемент
my_set.remove(1)     # Удаляем элемент
print(id(my_set))    # id остаётся ТЕМ ЖЕ

Неизменяемые для сравнения

# TUPLE — неизменяемый список
my_tuple = (1, 2, 3)
# my_tuple[0] = 99  # ОШИБКА!

# STRING — неизменяемая строка
my_str = "hello"
# my_str[0] = "H"  # ОШИБКА!

# При конкатенации создаётся НОВЫЙ объект
my_str = "hello"
id1 = id(my_str)
my_str = my_str + " world"
id2 = id(my_str)
print(id1 == id2)  # False — новый объект!

Проблемы с изменяемостью

Проблема 1: Неожиданные мутации

def process_list(data):
    data.append(999)  # Модифицируем исходный список!
    return data

original = [1, 2, 3]
result = process_list(original)
print(original)  # [1, 2, 3, 999] — УПС!

Проблема 2: Использование как ключ словаря

my_dict = {}
my_list = [1, 2, 3]
# my_dict[my_list] = "value"  # ОШИБКА!

my_tuple = (1, 2, 3)
my_dict[my_tuple] = "value"  # OK

Проблема 3: Значение по умолчанию в функции

# ПЛОХО!
def append_to_list(item, items=[]):
    items.append(item)
    return items

print(append_to_list(1))      # [1]
print(append_to_list(2))      # [1, 2] — НЕОЖИДАННО!

# ХОРОШО!
def append_to_list(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(append_to_list(1))      # [1]
print(append_to_list(2))      # [2]

Защита от нежелательных мутаций

1. Копирование данных

def process_list(data):
    data_copy = data.copy()  # Поверхностная копия
    data_copy.append(999)
    return data_copy

original = [1, 2, 3]
result = process_list(original)
print(original)  # [1, 2, 3] — не изменился!

2. Глубокая копия для вложенных структур

import copy

nested = [[1, 2], [3, 4]]
shallow = nested.copy()
deep = copy.deepcopy(nested)

shallow[0].append(999)
print(nested)   # [[1, 2, 999], [3, 4]] — изменился!
print(deep)     # [[1, 2], [3, 4]] — не изменился

3. Использование tuple вместо list где возможно

# Если не планируешь менять — используй tuple
coordinates = (10, 20)      # Более безопасно

# Возвращай tuple из функции
def get_position():
    return (100, 200)  # Защита от изменений

Производительность: изменяемость vs неизменяемость

import timeit

# LIST — изменяемый
list_code = '''
items = []
for i in range(1000):
    items.append(i)
'''

# TUPLE — неизменяемый
tuple_code = '''
items = ()
for i in range(1000):
    items = items + (i,)
'''

print("List time:", timeit.timeit(list_code, number=1000))
print("Tuple time:", timeit.timeit(tuple_code, number=1000))
# List НАМНОГО быстрее!

Dataclass и frozen датаклассы

from dataclasses import dataclass

# Изменяемый dataclass
@dataclass
class Person:
    name: str
    age: int

person = Person("Алиса", 30)
person.age = 31  # OK

# Неизменяемый dataclass
@dataclass(frozen=True)
class ImmutablePerson:
    name: str
    age: int

ip = ImmutablePerson("Боб", 25)
# ip.age = 26  # ОШИБКА!

Лучшие практики

  1. Используй изменяемость сознательно — если функция должна менять объект, документируй
  2. Предпочитай неизменяемость в параллелизме — нет race conditions
  3. Копируй, если сомневаешься — лучше небольшая потеря производительности
  4. Используй type hints — указывай list vs tuple для ясности
Что такое изменяемые структуры данных? | PrepBro