В КУРСЕ?

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

Изменили один список, изменился другой: что на самом деле копирует Python?

В Python два имени могут указывать на один и тот же список. Поэтому изменение через одно имя иногда неожиданно становится видно через другое. Это не случайное смешивание данных, а следствие того, как устроены присваивание и изменяемые объекты. Разберём разницу между новым именем и новой коллекцией, не переходя к сложным структурам.

Присваивание связывает имя с объектом

Пусть список numbers содержит значения пять, два и восемь. После присваивания other = numbers оба имени связаны с одним списком. Если добавить через other число один, при просмотре numbers тоже появится один. Отдельного списка операция присваивания не создала. Полезно мысленно рисовать два ярлыка, прикреплённых к одной коробке. Содержимое коробки меняется независимо от того, через какой ярлык к нему обратились. Такая схема помогает объяснять поведение до запуска программы, а не только замечать его после ошибки.

Отличать изменение объекта от нового присваивания

Добавление элемента через append меняет существующий список. А присваивание имени other совершенно нового списка меняет связь этого имени с объектом. После этого numbers продолжает указывать на прежний список. Это разные операции, хотя в разговоре обе иногда называют изменением переменной. Аналогично метод sort упорядочивает сам список и возвращает None, а функция sorted создаёт новый отсортированный список. Если нужно сохранить исходный порядок, важно выбрать подходящую операцию и не принимать возвращаемое значение изменяющего метода за готовую копию.

Понять границу поверхностной копии

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

Выбирать нужную степень независимости

Глубокое копирование предназначено для рекурсивного копирования составных объектов, но его не стоит применять автоматически к любой задаче. Некоторые данные должны оставаться общими, а некоторые объекты имеют особое поведение при копировании. Иногда достаточно создать новый список простых значений или явно собрать нужную структуру. Перед выбором полезно сформулировать требование: нужно ли менять только порядок элементов, добавлять новые элементы или независимо редактировать вложенные данные? Чем точнее описано ожидаемое поведение, тем проще выбрать операцию и проверить её на небольшом примере.

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

Проследите изменения на бумаге или в уже доступном интерпретаторе Python. Используйте только учебные списки, без настоящих файлов и пользовательских данных.

  1. Создайте список a со значениями пять, два и восемь и свяжите имя b с тем же списком присваиванием b = a.
  2. Добавьте через b число один и запишите содержимое a.
  3. Создайте c = a.copy(), добавьте в c число девять и сравните оба списка.
  4. Отдельно создайте вложенный список из двух строк: один, два и три, четыре; сделайте его поверхностную копию.
  5. Добавьте девять в первую внутреннюю строку через копию и объясните, почему изменение видно в оригинале.

Как проверить результат. После второго шага a содержит пять, два, восемь и один. Добавление девяти во внешний список c не меняет a. Но изменение общего внутреннего списка отражается в обеих вложенных структурах.

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

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

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

Поверхностная копия всегда неправильна?

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

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

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

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