Мелкое копирование и глубокое копирование в Python

RedDeveloper
09.03.2023 12:16
Мелкое копирование и глубокое копирование в Python

В python мы можем создать копию объекта с помощью оператора присваивания (=). Но есть проблема в использовании этого оператора для копирования объекта. Если вы внесете изменения в скопированный объект, это также приведет к изменению исходного объекта, с которого мы сделали копию.

Рассмотрим пример копирования объекта с помощью оператора присваивания.

# 'x' is a list of integers
x = [1,2,3,4,5]

# creating a copy of 'x' and assigned to 'y'
y = x

# displaying the contents of 'x' and 'y'
print('list x = ',x)
print('list y = ',y)

# trying to change the first element of 'y'
y[0] = 11

# displaying the contents of 'x' and 'y'
print('\nAfter changing the list y')
print('list x = ',x)
print('list y = ',y)

В приведенном выше сценарии мы создали список под названием 'x' с 5 целыми числами.

Затем создали копию 'x' и присвоили ей значение 'y'.

Мы изменяем первый элемент 'y' на 11. Когда мы изменяем

Список 'y', это также отразится в исходном списке 'x'.

Вывод для приведенного выше сценария

list x =  [1, 2, 3, 4, 5]
list y =  [1, 2, 3, 4, 5]

After changing the list y
list x =  [11, 2, 3, 4, 5]
list y =  [11, 2, 3, 4, 5]

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

Чтобы избежать этой проблемы, мы можем скопировать объект с помощью модуля 'copy'.

Существует два варианта копий, доступных из этого модуля. Это поверхностное копирование с помощью метода copy() и глубокое копирование с помощью метода deepcopy().

Сначала рассмотрим неглубокое копирование. Чтобы использовать метод copy() и deepcopy(), мы должны импортировать модуль 'copy'.

Неглубокое копирование

import copy

# a list with elements and nested list
x = [1,2,3,[4,5,6]]

# creating a shallow copy of 'x' 
y = copy.copy(x)

# changing the element of list 'y'
y[0]=100

# displaying the contents of 'x' and 'y'
print('\nAfter changing an element in y')
print('list x = ',x)
print('list y = ',y)

# changing the element in the nested list of 'y'
y[3][0]=400

# displaying the contents of 'x' and 'y'
print('\nAfter changing the nested list in y')
print('list x = ',x)
print('list y = ',y)

В приведенном выше сценарии список 'x' содержит 3 целых числа и является вложенным списком (список внутри списка). Затем мы создаем копию 'x' и присваиваем ее 'y'.

После этого мы пытаемся изменить первый элемент(y[0]) на 100 в списке 'y'. Затем мы отображаем содержимое обоих списков 'x' и 'y'. Мы видим, что y[0] меняется на 100, а x[0] не меняется.

До сих пор проблем не было. Здесь проблема возникает, когда мы изменяем вложенный список в 'y'. Здесь мы пытаемся изменить первый элемент(y[3][0]) на 400 из вложенного списка в 'y'. После изменения и отображения содержимого обоих 'x' и 'y', мы можем наблюдать, что изменения, которые мы сделали во вложенном списке 'y', также отражаются в списке 'x'.

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

Вывод для приведенного выше сценария

After changing an element in y
list x =  [1, 2, 3, [4, 5, 6]]
list y =  [100, 2, 3, [4, 5, 6]]

After changing the nested list in y
list x =  [1, 2, 3, [400, 5, 6]]
list y =  [100, 2, 3, [400, 5, 6]]

Глубокое копирование

Чтобы клонировать дочерние объекты, мы можем использовать метод deepcopy() в модуле copy.

Для демонстрации глубокого копирования мы можем использовать тот же сценарий, что и для поверхностного копирования. Вместо метода copy() мы можем использовать метод deepcopy(), чтобы скопировать список 'x' и присвоить ему значение 'y'.

import copy

# a list with elements and nested list
x = [1,2,3,[4,5,6]]

# creating a deep copy of 'x' 
y = copy.deepcopy(x)

# changing the element of list 'y'
y[0]=100

# displaying the contents of 'x' and 'y'
print('\nAfter changing an element in y')
print('list x = ',x)
print('list y = ',y)

# changing the element in the nested list of 'y'
y[3][0]=400

# displaying the contents of 'x' and 'y'
print('\nAfter changing the nested list in y')
print('list x = ',x)
print('list y = ',y)

Здесь мы пытаемся изменить первый элемент(y[3][0]) на 400 из вложенного списка в 'y'. После изменения и отображения содержимого обоих 'x' и 'y' мы можем наблюдать, что изменения, которые мы сделали во вложенном списке 'y', не изменили вложенный список 'x'.

Вывод для приведенного выше сценария

After changing an element in y
list x =  [1, 2, 3, [4, 5, 6]]
list y =  [100, 2, 3, [4, 5, 6]]

After changing the nested list in y
list x =  [1, 2, 3, [4, 5, 6]]
list y =  [100, 2, 3, [400, 5, 6]]

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

Типы данных JavaScript
Типы данных JavaScript

27.03.2023 13:18

В JavaScript существует несколько типов данных, включая примитивные типы данных и ссылочные типы данных. Вот краткое объяснение различных типов данных в JavaScript с примерами:

Как сделать движок для футбольного матча? (простой вариант)
Как сделать движок для футбольного матча? (простой вариант)

27.03.2023 12:01

Футбол. Для многих людей, живущих на земле, эта игра - больше, чем просто спорт. И эти люди всегда мечтают стать футболистом или менеджером. Но, к сожалению, большинство из них не могут подняться по лестнице успеха, и эти идеи застревают на стадии мечты. В этот момент на помощь приходят футбольные...

Знайте свои исключения!
Знайте свои исключения!

27.03.2023 11:58

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

CSS Flex: что должен знать каждый разработчик
CSS Flex: что должен знать каждый разработчик

27.03.2023 11:55

CSS Flex: что должен знать каждый разработчик Модуль flexbox, также известный как гибкий модуль разметки box, помогает эффективно проектировать и создавать отзывчивые веб-страницы без использования множества свойств позиционирования и float. По умолчанию в flex-контейнере есть только одна...

Введение в раздел "Заголовок" в HTML
Введение в раздел "Заголовок" в HTML

26.03.2023 13:40

Говорят, что лучшее о человеке можно увидеть только изнутри, и это относится и к веб-страницам HTML! Причина, по которой некоторые веб-страницы не видны в поисковых системах, заключается в том, что им не хватает функций, обеспечивающих их видимость.