In Python, If we do assignment for mutable objects like Lists, we think it will create a new object but it doesn't. It will only create a new variable that shares the same object.
>>> l1 = [1,2,3,4]
>>> id(l1)
140257285907200
>>> l2 = l1
>>> id(l2)
140257285907200
Here we can see the same object for l1and l2 lists. if we update any of the list it will effect the other list as well.
>>> l2.append(5)
>>> l2
[1, 2, 3, 4, 5]
>>> l1
[1, 2, 3, 4, 5]
So here object is getting updated, not the variable. To overcome this issue Deep Copy and Shallow Copy will come into the picture.
Shallow Copy: We have to import copy to do shallow copy.
>>> import copy
>>> l1 = [1,2,3,4]
>>> l2 = copy.copy(l1)
>>> id(l1)
140257285917760
>>> id(l2)
140257286016832
Here we can notice there are two different objects got created. if we do any updates on the lists it wont effect others.
>>> l2.append(5)
>>> l2
[1, 2, 3, 4, 5]
>>> l1
[1, 2, 3, 4]
Deep Copy: For Deep Copy also we have to import copy module
In simple terms, like in the name it will do the copy deeply, In the below example we will find out what is wrong with shallow copy.
>>> l1 = [1,2,3,[5,4]]
>>> l2 = copy.copy(l1)
>>> l1
[1, 2, 3, [5, 4]]
>>> l2
[1, 2, 3, [5, 4]]
>>> id(l1)
140658698642944
>>> id(l2)
140658698638016
We know that, if we do shallow copy it will create two objects, but in the above example we have a nested list. For nested list also python will create the object.
>>> id(l1[3])
140658698642816
>>> id(l2[3])
140658698642816
Nested list having same object reference for l1 and l2 lists, if we perform any operation on the nested list it will effect the other list as well.
>>> l2[3][0]=100
>>> l2
[1, 2, 3, [100, 4]]
>>> l1
[1, 2, 3, [100, 4]]
We updated the nested list of l2, but it's effected the l1 as well. To overcome this we will use Deep Copy.
>>> l1 = [1,2,3,[55,66]]
>>> l2 = copy.deepcopy(l1)
>>> l1
[1, 2, 3, [55, 66]]
>>> l2
[1, 2, 3, [55, 66]]
>>> l2[3][0]=100
>>> l2
[1, 2, 3, [100, 66]]
>>> l1
[1, 2, 3, [55, 66]]