В этом уроке мы собираемся обсудить поверхностное (shallow) и глубокое (deep) копирование с помощью примеров на Python. Мы рассмотрим определение глубокого и поверхностного копирования, а также их реализации на языке Python, чтобы оценить основные различия между двумя типами копирования.
Во многих программах, которые мы пишем, нам часто приходится копировать объекты по какой либо причине, например, из-за улучшения вычислительной эффективности. Есть два способа сделать это: сделать полную копию или поверхностную копию. Прежде чем мы обсудим различия между ними, давайте сначала рассмотрим, что такое глубокое и поверхностное копирование.
Глубокая копия создает новую и отдельную копию всего объекта или списка со своим уникальным адресом памяти. Это означает, что любые изменения, внесенные вами в новую копию объекта или списка, не будут отражаться в исходной. Этот процесс происходит следующим образом, сначала создается новый список или объект, а затем рекурсивно копируя все элементы из исходного в новый.
Короче говоря, оба объекта становятся полностью независимы друг от друга. Это похоже на концепцию передачи по значению в таких языках, как C ++, Java и C #.
Для реализации концепции глубокого копирования в Python мы будем использовать модуль copy.
Допустим, у нас есть список с именем result_A, который содержит оценки ученика A по 3 предметам, и мы хотим создать точно такой же список результатов и для ученика B. Мы сделаем глубокую копию списка result_A и позже сделаем несколько изменений в этой копии, чтобы посмотреть на оценки ученика B.
Пример 1:
# Program 1 - Deep Copy import copy result_A = [90, 85, 82] # Student A grades result_B = copy.deepcopy(result_A) # Student B grades (copied from A) print(result_A) print(result_B)
В приведенном выше сценарии мы используем метод deepcopy из модуля copy, чтобы скопировать список result_A в result_B. Далее мы печатаем содержимое обоих списков на экране.
[90, 85, 82] [90, 85, 82]
Как видите, списки идентичны. Позже в этой статье мы рассмотрим, как они отличается от результата поверхностного копирования.
Поверхностное копирование также создает отдельный новый объект или список, но вместо копирования дочерних элементов в новый объект, оно просто копирует ссылки на их адреса памяти. Следовательно, если вы сделаете изменение в исходном объекте, оно будет отражено в скопированном объекте, и наоборот. Короче говоря, обе копии зависят друг от друга. Это похоже на концепцию передачи по ссылке в таких языках программирования, как C ++, C # и Java.
Чтобы реализовать это в Python, мы снова будем использовать модуль copy, но на этот раз мы будем использовать функцию copy.
Давайте воспользуемся тем же списком.
Пример 2:
# Program 2 - Shallow Copy import copy result_A = [95, 85, 82] result_B = copy.copy(result_A) print(result_A) print(result_B)
В приведенном выше сценарии мы используем метод copy из модуля copy, чтобы сделать поверхностную копию списка result_A, который мы назвали result_B. Далее содержимое обоих списков было напечатано на консоли.
[90, 85, 82] [90, 85, 82]
Опять же, такие же списки, как и ожидалось. Далее мы объясним разницу между результатами, которые мы получаем от функций copy и deepcopy.
Теперь, когда мы обсудили, что такое поверхностное и глубокое копирование, пришло время поговорить о разнице между ними. По сути, есть только два основных различия, и они связаны друг с другом:
Прежде чем мы перейдем к примеру в котором будет рассмотрена разница, я бы хотел, чтобы вы представили аналогию для сценария примера. Допустим, два человека хотят поделиться напитком; у них два пустых стакана и две соломинки. Они могут поделиться напитком двумя способами:
Первый сценарий — сценарий это аналогия поверхностного копирования. Обе переменные/экземпляры используют одну и ту же ячейку памяти для своих операций. Второй сценарий — сценарий глубокого копирования. Обе переменные/экземпляры используют две разные области памяти для своих операций.
Чтобы прояснить разницу, давайте использовать эту информацию в наших двух приведенных выше примерах, начиная с примера 1.
Выше мы создали список result_A и сделали его полную копию с именем result_B. Давайте попробуем изменить содержимое в result_B и посмотрим, повлияет ли это на содержимое result_A.
# This code is an extension of Program 1. # Copy and paste the below lines in your Example 1 # Change first subject's marks to 30 result_B[0] = 30 print("Original List: ") print(result_A) print("Deep Copy:") print(result_B)
Original List: [90, 10, 85, 82] Deep Copy: [30, 10, 85, 82]
Ожидаемый результат заключается в том, что первоначальный список остается без изменений. И, как вы видите, изменения в глубокой копии не повлияли на исходный список.
Теперь давайте попробуем то же самое с примером 2 — поверхностное копирование.
# This code is an extension of Program 2. # Copy and paste the below lines in Example 2 result_B[0] = 30 print("Original List: ") print(result_A) print("Shallow Copy:") print(result_B)
# Expected Outcome: Original list gets modified as well Original List: [30, 10, 85, 82] Shallow Copy: [30, 10, 85, 82]
Здесь ожидаемый результат состоит в том, что как исходный список, так и скопированный список изменяются. И, как вы можете видеть, внесение изменений в поверхностную копию привело к тому, что эти изменения также были отражены в исходном списке.
В этом посте мы говорили о том, что такое поверхностное и глубокое копирование и как они реализуются на языке Python, используя модуль «copy». Мы использовали две его функции, а именно: copy и deepcopy. Кроме того, мы обсудили два основных различия между поверхностной и глубокой копией, а также реализовали поверхностное и глубокое копирование в python, чтобы лучше понять эти различия.
Оригинал: Deep vs Shallow Copies in Python
Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…
Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…
Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…
Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…
Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…
Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…
View Comments
А разве при поверхностном копировании с помощью импортированной функции copy.copy(), ссылочное копирование происходит не только с элементами списка которые сами являются списком? То есть в вашем примере поверхностного копирования переменные будут ссылаться на два различных объекта, так как ссылочных элементов внутри списка нет и изменения первого не затронут изменение второго.
Согласен. По смыслу статьи непонятно, чем тогда copy.copy() отличается от простого присваивания b = a
Вы переводчик, все статьи переводы
И что? если статьи помогают освоить Python, то какая разница откуда они?
спасибо автору! (даже если он переводчик)
Автор балбес. Поленился даже свой код проверить. В вашем случае при поверхностном копировании списки будут разные, а не как в вашем коде. Для примера нужно использовать вложенные списки. Ну и кретин!
А еще он не упомянул, что вложенные классы не копируются даже через copy.deepcopy()
and https://stackoverflow.com/a/32791606/3275135
Кстати, в конце данной статьи, есть ссылка на оригинальную статью, где все в порядке с примерами, все они содержат вложенные списки )