Рубрики
Без рубрики

Глубокие и неглубокие копии в Python

Автор оригинала: Guest Contributor.

Глубокие и неглубокие копии в Python

Вступление

В этом уроке мы обсудим неглубокие копии против глубоких копий с помощью примеров в Python. Мы рассмотрим определение глубокой и неглубокой копии, а также ее реализацию на языке Python, чтобы оценить основные различия между этими двумя типами копий.

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

Глубокие копии в Python

Глубокая копия создает новую и отдельную копию всего объекта или списка со своим собственным уникальным адресом памяти. Это означает, что любые изменения, внесенные вами в новую копию объекта/списка, не будут отражены в исходной. Этот процесс происходит сначала путем создания нового списка или объекта, а затем рекурсивного копирования элементов из исходного в новый.

Короче говоря, оба объекта полностью независимы друг от друга. Это похоже на концепцию передачи по значению в таких языках, как C++, Java и C#.

Пример Глубокого Копирования

Для реализации концепции глубоких копий в Python мы будем использовать модуль copy .

Допустим , у нас есть список списков под названием result_A , который содержит оценки ученика А по 3 предметам за первые два года обучения в школе, и мы хотим создать точно такой же список результатов и для ученика В. Мы попробуем сделать глубокую копию списка result_A и позже внесем несколько изменений в эту глубокую копию, чтобы показать оценки ученика Б.

Пример 1:

# Program 1 - Deep Copy
import copy

result_A = [[90, 85, 82], [72, 88, 90]] # 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], [72, 88, 90]]
[[90, 85, 82], [72, 88, 90]]

Как видите, списки идентичны. Позже в этой статье мы увидим, чем это отличается от неглубоких копий.

Неглубокие копии в Python

Неглубокая копия также создает отдельный новый объект или список объектов, но вместо копирования дочерних элементов в новый объект она просто копирует ссылки на их адреса памяти. Следовательно, если вы внесете изменения в исходный объект, они отразятся на скопированном объекте, и наоборот. Короче говоря, обе копии зависят друг от друга. Это похоже на концепцию передачи по ссылке в таких языках программирования, как C++, C# и Java.

Пример Неглубокого Копирования

Чтобы реализовать это в Python, мы снова будем использовать модуль copy , но на этот раз мы будем вызывать его функцию copy .

Давайте также используем тот же список примеров для примера неглубокой копии.

Пример 2:

# Program 2 - Shallow Copy
import copy

result_A = [[90, 85, 82], [72, 88, 90]]
result_B = copy.copy(result_A)

print(result_A)
print(result_B)

В приведенном выше скрипте мы используем метод copy из модуля copy для создания неглубокой копии списка result_A , который мы назвали result_B . Затем содержимое обоих списков было напечатано на консоли.

Выход:

[[90, 85, 82], [72, 88, 90]]
[[90, 85, 82], [72, 88, 90]]

Опять же, списки те же, что и ожидалось. Далее мы объясним разницу между результатами, которые мы получаем от функций copy и deepcopy .

Разница между Глубокими и Мелкими копиями

Теперь, когда мы обсудили, что такое поверхностные и глубокие копии и почему мы создаем копии, пришло время поговорить о различии между ними. По сути, есть только два основных различия, и они связаны друг с другом:

  1. Deep copy хранит копии значений объекта , в то время как shallow copy stories ссылки на исходный адрес памяти
  2. Глубокая копия не отражает изменений, внесенных в новый/скопированный объект в исходном объекте; в то время как мелкая копия

Прежде чем мы перейдем к реализации, я хотел бы, чтобы вы представили себе этот сценарий. Допустим, два человека хотят выпить вместе; у них есть два пустых стакана и две соломинки. Они могут разделить этот напиток двумя способами:

  1. Положите напиток в один стакан и положите обе соломинки в этот стакан для совместного использования
  2. Налейте напиток в оба стакана и положите по одной соломинке в каждый стакан

Первый сценарий – это неглубокая копия. Обе переменные/экземпляры указывают/используют одну и ту же ячейку памяти для своих операций. Второй сценарий-это глубокая копия. Обе переменные/экземпляры указывают на/используют две разные области памяти для своих операций.

Пример Сравнения

Чтобы прояснить разницу, давайте воспользуемся этой информацией в двух приведенных выше примерах, начиная с Примера 1 .

Выше мы создали список result_A и сделали его глубокую копию с именем result_B . Давайте попробуем изменить содержимое в result_B и посмотрим, повлияет ли это на содержимое result_A .

import copy

result_A = [[90, 85, 82], [72, 88, 90]] # Student A grades
result_B = copy.deepcopy(result_A) # Student B grades (copied from A)

# Change first year and first subject's marks to 30
result_B[0][0] = 30

print("Original List: ")
print(result_A)
print("Deep Copy:")
print(result_B)

Выход:

Original List:
[[90, 85, 82], [72, 88, 90]]
Deep Copy:
[[30, 85, 82], [72, 88, 90]]

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

Теперь давайте попробуем то же самое с Примером 2 – Мелкая копия.

import copy

result_A = [[90, 85, 82], [72, 88, 90]] # Student A grades
result_B = copy.copy(result_A) # Student B grades (copied from A)

# Change first year and first subject's marks to 30
result_B[0][0] = 30

print("Original List: ")
print(result_A)
print("Shallow Copy:")
print(result_B)

Выход:

Original List:
[[30, 85, 82], [72, 88, 90]]
Shallow Copy:
[[30, 85, 82], [72, 88, 90]]

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

Вывод

В этом посте мы говорили о том, что такое неглубокая и глубокая копия и как мы можем сделать их на языке Python с помощью модуля “копия”. Мы использовали две его функции: copy и deepcopy для создания неглубоких и глубоких копий соответственно. Кроме того, мы обсудили два основных различия между неглубокой и глубокой копией, а также реализовали неглубокую и глубокую копию в python, чтобы лучше понять эти различия.