Wednesday, 18 September 2013

Shallow and deep copying

According to reference semantics, we know that only reference are meaningful than real objects.
There are certain crucial problems, which can occur when copying mutable objects, like copying lists and dictionaries.

Copying with the slice operator

It's possible to completely copy shallow lists with the slice operator without any problem, which is described below:
>>> l=[1,2,3,4]
>>> l2=l[:]
>>> print l
[1, 2, 3, 4]
>>> print l2
[1, 2, 3, 4]
>>> l.append(5)
>>> print l2
[1, 2, 3, 4]
>>> print l
[1, 2, 3, 4, 5]

But as soon as a list contains sublists, we have the some difficulty, i.e. just references to the sublists are copied and not the actual members of the lists.

>>> #shallow copying
...
>>>
>>>
>>> a=[1,2,3,[4,5],6,7,[8,9],10]
>>> b=a
>>> c=a[:]
>>> print b
[1, 2, 3, [4, 5], 6, 7, [8, 9], 10]
>>> print c
[1, 2, 3, [4, 5], 6, 7, [8, 9], 10]
>>> a.append(11)
>>> print a
[1, 2, 3, [4, 5], 6, 7, [8, 9], 10, 11]
>>> print b
[1, 2, 3, [4, 5], 6, 7, [8, 9], 10, 11]
>>> print c
[1, 2, 3, [4, 5], 6, 7, [8, 9], 10]
>>> a[3].append('innerlist')
>>> print a
[1, 2, 3, [4, 5, 'innerlist'], 6, 7, [8, 9], 10, 11]
>>> print b
[1, 2, 3, [4, 5, 'innerlist'], 6, 7, [8, 9], 10, 11]
>>> print c
[1, 2, 3, [4, 5, 'innerlist'], 6, 7, [8, 9], 10]
>>>
 
This behaviour is depicted in the following diagram: 

In this case, while lst1 is copied into lst2 only the reference which was there in lst1 is copied and not the original values.
If you assign a new value to the 0th Element of one of the two lists, there will be no side effect. Problems arise, if you change one of the elements of the sublist. 
           
                   
              Copying a list with sublists



The following diagram depicts what happens, if one of the elements of a sublist will be changed: Both the content of lst1 and lst2 are changed.

         
                 Copying lists containing sublists

Method of deep copying

Deepcopy is a "method" which needs to be imported from the module copy.

The following script uses our example above and this method:
>>> from copy import deepcopy
>>>lst1 = ['a','b',['ab','ba']] 
>>>lst2 = deepcopy(lst1) 
>>>lst2[2][1] = "d" 
>>>lst2[0] = "c"; 
>>>print lst2
['c','b',['ab','d']]
>>> print lst1
['a','b',['ab','ba']]

                    Copy a list with Deep-Copy











0 comments:

Post a Comment