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

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

Вступление

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

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

Глубокие копии на Python

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

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

Пример глубокой копии

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

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

Пример 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. Глубокие копирования хранят копию значений объекта перечисляется , тогда как мелкая копия историй ссылка на исходный адрес памяти
  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 - Shallow Copy.

 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 с помощью модуля «копировать». Мы использовали две его функции, а deepcopy copy для создания мелких и глубоких копий соответственно. Кроме того, мы обсудили два основных различия между мелкой и глубокой копией, а также реализовали мелкую и глубокую копию в Python, чтобы лучше понять эти различия.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus