Methods to clone a python list
Python list are one of the most used data structure. An improper cloning of a list has burnt more midnights’ oil than creation & manipulation of the list has taken. Cloning isn’t difficult but plain different. Of course, I am not considering the most obvious method iterate through the list and create a new list 🙂
list_1 = [1,2,3] list_2 = [4,5,6] original = [ list_1, list_2 ]
Clone by assignment
new = original
The new list “new” points to the original list. So, any changes to the original list will be reflected in the new list.
list_1 = [1,2,3] list_2 = [4,5,6] original = [ list_1, list_2 ] new = original print 'original: ', original print 'new: ', new list_2.append(7) list_3 = [8, 9] original.append(list_3) print '********************************' print 'original: ', original print 'new: ', new1
$ python clone-by-assign.py original: [[1, 2, 3], [4, 5, 6]] new: [[1, 2, 3], [4, 5, 6]] ******************************** original: [[1, 2, 3], [4, 5, 6, 7], [8, 9]] new: [[1, 2, 3], [4, 5, 6, 7], [8, 9]]
Clone by slice
new = original[:]
The new list “new” creates a copy of original list but shares the content with the original list. So, any changes to the original list will NOT affect the new list but changes to the content will alter the new2 as well.
list_1 = [1,2,3] list_2 = [4,5,6] original = [ list_1, list_2 ] new = original[:] print 'original: ', original print 'new: ', new list_2.append(7) list_3 = [8, 9] original.append(list_3) print '********************************' print 'original: ', original print 'new: ', new
$ python clone-by-slice.py original: [[1, 2, 3], [4, 5, 6]] new: [[1, 2, 3], [4, 5, 6]] ******************************** original: [[1, 2, 3], [4, 5, 6, 7], [8, 9]] new: [[1, 2, 3], [4, 5, 6, 7]]
Clone by copy constructor
new = list(original)
This is exactly same as the clone by slice.
$ python clone-by-copy-constructor.py original: [[1, 2, 3], [4, 5, 6]] new: [[1, 2, 3], [4, 5, 6]] ******************************** original: [[1, 2, 3], [4, 5, 6, 7], [8, 9]] new: [[1, 2, 3], [4, 5, 6, 7]]
Clone by copy module
There is a copy module that can be imported and gives 2 different methods to copy:
- copy()
- deepcopy()
Cloning by copy()
This is exactly same as slice & copy-constructor.
import copy new = copy.copy(original)
This is exactly same as the clone by slice, returns a shallow copy of the original.
$ python clone-by-copy.py original: [[1, 2, 3], [4, 5, 6]] new: [[1, 2, 3], [4, 5, 6]] ******************************** original: [[1, 2, 3], [4, 5, 6, 7], [8, 9]] new: [[1, 2, 3], [4, 5, 6, 7]]
Cloning by deepcopy()
This is the ultimate copy that we might require. This creates an entirely new list, which has no bindings whatsoever with the original list.
list_1 = [1,2,3] list_2 = [4,5,6] original = [ list_1, list_2 ] new = copy.deepcopy(original) print 'original: ', original print 'new: ', new list_2.append(7) list_3 = [8, 9] original.append(list_3) print '********************************' print 'original: ', original print 'new: ', new
$ python clone-by-deepcopy.py original: [[1, 2, 3], [4, 5, 6]] new: [[1, 2, 3], [4, 5, 6]] ******************************** original: [[1, 2, 3], [4, 5, 6, 7], [8, 9]] new: [[1, 2, 3], [4, 5, 6]]
So, depending on the requirement, the appropriate clone method should be chosen.
The blogs/forums I referred to:
- Laurent Luce’s Blog: Beautiful explanation of python lists. Do check out the comments sections for furthering your knowledge with time complexity et al 🙂
- Stackoverflow discussion: Some fabulous responses including speed comparison.
Leave a Reply