Copy - Shallow and deep copy operations in Python

PythonServer Side ProgrammingProgramming

In Python a variable is just a reference to object. Hence when it is assigned to another variable, it doesn’t copy the object, rather it acts as another reference to same object. This can be verified by using id() function

>>> L1 = [1,2,3]
>>> L2 = L1
>>> id(L1), id(L2)
(2165544063496, 2165544063496)

Result of above code shows that id() for both list objects is same, which means both refer to same object. The L2 is said to be a shallow copy of L1. Since both refer to same object, any change in either will reflect in other object.

>>> L1 = [1,2,3]
>>> L2 = L1
>>> L2[1] = 100
>>> L1,L2
([1, 100, 3], [1, 100, 3])

In above example, item at index no. 1 of L2 is changed. We see this change appearing in both.

When an entirely new object is created with the copying operation, with copies of nested objects too are recursively added to it, the copy is called deep copy.

The copy module of Python standard library provides two methods:

  • copy.copy() – creates a shallow copy
  • copy.deepcopy() – creates a deep copy

A shallow copy creates a new object and stores the reference of the original elements but doesn't create a copy of nested objects. It just copies the reference of nested objects. As a result, copy process is not recursive.

>>> import copy
>>> L1 = [[1,2,3], [4,5,6]]
>>> L2 = copy.copy(L1)
>>> L1,L2
([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]])
>>> L2.append([10,10,10])
>>> L1,L2
([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6], [10, 10, 10]])

Here L1 is a nested list and L2 is its shallow copy. Although reference to parent list object is copied into L2, its nested elements are not copied. Hence, when we append another list to L2, it is not reflected in L1

However, if we try to modify an element in child element, its effect will be seen in both lists

>>> L1 = [[1,2,3], [4,5,6]]
>>> L2 = copy.copy(L1)
>>> L1,L2
([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]])
>>> L2[1][0] = 100
>>> L1,L2
([[1, 2, 3], [100, 5, 6]], [[1, 2, 3], [100, 5, 6]])

A deep copy however, creates a new object and recursively adds the copies of nested objects too, present in the original elements.

In following example, L2 is a deep copy of L2. Now if we change any element of inner list, this will not show in other list.

>>> L1 = [[1,2,3], [4,5,6]]
>>> L2 = copy.deepcopy(L1)
>>> L1,L2
([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]])
>>> L2[1][0] = 100
>>> L1,L2
([[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [100, 5, 6]])

Effect of deep copy is thus verified by the output.

raja
Published on 16-Apr-2019 15:11:10
Advertisements