В КУРСЕ?

Разбираемся в теме

Изменили один список, а поменялись два: почему присваивание в Python не создаёт копию

Начинающий программист нередко сохраняет список под вторым именем, чтобы оставить исходные данные нетронутыми. Затем добавляет элемент через новое имя и обнаруживает изменение в исходном списке. Причина связана с устройством присваивания: новое имя может указывать на тот же объект. Понять это проще на маленьком примере, где каждое изменение видно отдельно.

Два имени могут вести к одному объекту

Создадим список командой a = [2, 5], а затем выполним b = a. Здесь не появляется второй независимый список. Оба имени связаны с одним изменяемым объектом. После b.append(9) обращение к a и обращение к b покажут одинаковое содержимое: [2, 5, 9]. Представьте одну корзину с двумя подписанными указателями. Добавление предмета через любой указатель меняет содержимое единственной корзины. Такая аналогия помогает объяснить именно общую связь имён со списком. Она не означает, что все операции Python ведут себя одинаково: важно различать изменение объекта и новое присваивание имени.

Копия отделяет внешний список

Начнём заново: a = [2, 5], затем b = a.copy(). Теперь существуют два внешних списка. Добавление b.append(9) изменяет только второй: a сохраняет [2, 5], а b содержит [2, 5, 9]. Для списка целых чисел это часто соответствует ожидаемому поведению. Но метод copy создаёт поверхностную копию. Если элементами являются другие изменяемые объекты, они могут оставаться общими. Пусть a = [[2], [5]], после чего b = a.copy(). Команда b[0].append(9) меняет вложенный список, доступный из обеих внешних коллекций. В результате оба имени показывают [[2, 9], [5]]. Новая внешняя оболочка не означает независимость всего содержимого.

Проверяйте, что именно меняется

В каждом примере полезно задавать два вопроса: какой объект сейчас изменяется и какие имена позволяют до него добраться. Команда b.append добавляет элемент во внешний список. Команда b[0].append сначала выбирает вложенный список, а затем изменяет уже его. Одинаковое слово append не делает эти операции равнозначными по месту воздействия. Ещё один случай — b = [8]. Это новое присваивание связывает имя b с другим списком и само по себе не переписывает список, доступный через a. Поэтому при отладке недостаточно заметить, что строка содержит букву b. Нужно определить тип действия. Для более сложных структур существует глубокое копирование, но прежде полезно понять, какие общие объекты действительно должны стать независимыми.

Попробуйте на практике

Проверьте три коротких сценария в отдельном учебном файле или интерактивном интерпретаторе Python.

  1. Для первого сценария создайте a = [2, 5], выполните b = a и b.append(9). До запуска предскажите содержимое обоих списков, затем выведите их.
  2. Начните второй сценарий с нового a = [2, 5]. Используйте b = a.copy(), добавьте девятку через b и сравните результат с первым сценарием.
  3. Для третьего сценария задайте a = [[2], [5]], выполните b = a.copy(), затем b[0].append(9). Отметьте, какой именно вложенный объект изменился.
  4. Нарисуйте для каждого случая имена, внешние списки и стрелки к вложенным объектам. Исправьте схему там, где она не объясняет полученный вывод.

Как проверить результат. В первом случае изменение видно через оба имени. Во втором исходный список остаётся [2, 5]. В третьем общий внутренний список становится [2, 9], хотя внешние списки созданы отдельно.

Частые вопросы

Одинаковое содержимое означает один объект?

Нет. Два разных списка могут содержать одинаковые элементы. Равенство содержимого и общая ссылка на объект — разные свойства, поэтому одного визуального сравнения вывода недостаточно.

Нужно ли копировать список при каждом присваивании?

Нет. Общий объект иногда нужен намеренно. Решение зависит от того, должны ли дальнейшие изменения быть видны всем участкам программы, которые используют этот список.

Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.

Зарегистрируйтесь, чтобы уточнить возможность доступа к этому материалу

Зарегистрироваться
← К списку материалов