1.

What according to you is the difference between shallow copy and deep copy?

Answer»

Unlike C/C++, a variable in PYTHON is just a label to object created in memory. Hence when it is assigned to another variable, it doesn’t copy the object, but rather it acts as another reference to the same object. The built-in id() function brings out this behaviour.

>>> num1=[10,20,30]  >>> num2=num1  >>> num1  [10, 20, 30]  >>> num2  [10, 20, 30]  >>> id(num1), id(num2)  (140102619204168, 140102619204168)

The id() function returns the location of object in memory. Since id() for both the list objects is the same, both refer to the same object in memory.

The num2 is called as a shallow copy of num1. Since both refer to the same object, any change in either will reflect in the other object.

>>> num1=[10,20,30] >>> num2=num1 >>> num2[2]=5 >>> num1 [10, 20, 5] >>> num2 [10, 20, 5]

In the above example, the item at index no. 2 of num2 is changed. We see this change appearing in both.

A deep copy creates an entirely new object and COPIES of nested objects too are recursively added to it.

The copy module of the 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, the copy process is not recursive.

>>> import copy >>> num1=[[1,2,3],['a','b','c']] >>> num2=copy.copy(num1) >>> id(num1),id(num2) (140102579677384, 140102579676872) >>> id(num1[0]), id(num2[0]) (140102579676936, 140102579676936) >>> num1[0][1],id(num1[0][1]) (2, 94504757566016) >>> num2[0][1],id(num2[0][1]) (2, 94504757566016)

Here num1 is a nested list and num2 is its shallow copy. Ids of num1 and num2 are different, but num2 doesn’t hold physical copies of internal elements of num1, but holds just the ids.

As a result, if we try to modify an ELEMENT in nested element, its effect will be seen in both lists.

>>> num2[0][2]=100 >>> num1 [[1, 2, 100], ['a', 'b', 'c']] >>> num2 [[1, 2, 100], ['a', 'b', 'c']]

However, if we append a new element to one list, it will not reflect in the other list.

>>> num2.append('Hello') >>> num2 [[1, 2, 100], ['a', 'b', 'c'], 'Hello'] >>> num1 [[1, 2, 100], ['a', 'b', 'c']]

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

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

>>> import copy >>> num1=[[1,2,3],['a','b','c']] >>> num2=copy.deepcopy(num1) >>> id(num1),id(num2) (140102641055368, 140102579678536) >>> num2[0][2]=100 >>> num2 [[1, 2, 100], ['a', 'b', 'c']] >>> num1 #not changed [[1, 2, 3], ['a', 'b', 'c']]


Discussion

No Comment Found