В 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]]
Глубокое копирование создает новый составной объект. Затем, рекурсивно, вставляет копии элементов, найденных в исходном составном объекте, во вновь созданный составной объект. Счастливого кодирования!!!
20.08.2023 18:21
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в 2023-2024 годах? Или это полная лажа?".
20.08.2023 17:46
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
19.08.2023 18:39
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в частности, магию поплавков и гибкость flexbox.
19.08.2023 17:22
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для чтения благодаря своей простоте. Кроме того, мы всегда хотим проверить самые последние возможности в наших проектах!
18.08.2023 20:33
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий их языку и культуре.
14.08.2023 14:49
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип предназначен для представления неделимого значения.