next up previous contents
Next: Object Persistence: the pickle/cPickle Up: Using Modules Previous: Information about your Python   Contents


Copying: the copy module

As mentioned in Section 6.1, assignments generally create references to objects, and don't really create a new location in memory containing a copy of the data being assigned. For lists which contain simple data (such as scalar numbers and scalar strings), simply providing a colon in the subscript when copying is sufficient to make a true copy. The copy function of the copy module provides this same capability through a function. Thus, given a list of scalar values, the following two statements are equivalent:
newx = x[:]
newx = copy.copy(x)
If the elements of the object you're trying to copy are not scalars, however, the copy of x stored in newx will actually contain references to the non-scalar objects, and not true copies of those objects. In cases like this, the deepcopy function can be used. This function recursively duplicates all the elements stored in a Python object, and provides a true copy of arbitrary objects in most cases.

As a simple illustration of the difference between copy and deepcopy, consider a list of lists. Note what happens to the two copied objects newx and deepx when an element of one of the nested lists in the original object x is changed:

>>> x = [[1,2,3],['cat','dog','mouse','duck'],[7,8]]
>>> newx = copy.copy(x)
>>> deepx = copy.deepcopy(x)
>>> 
>>> x[1][1] = 'gorilla'
>>> newx[1][1]
'gorilla'
>>> deepx[1][1]
'dog'
When we change an element in one of the nested lists of x, that change is reflected in newx, since it simply copied references to each of the nested lists; the value in deepx remains unchanged since it was created with a deep copy. Of course, if we replace an element of the original list, Python will realize that the copies are now the only objects referencing the original value, and both types of copies will retain the original values; the difference between the two methods of copying is only apparent when individual elements of nested objects are modified:
>>> x[2] = [107,108]
>>> newx[2]
[7, 8]
>>> deepx[2]
[7, 8]


next up previous contents
Next: Object Persistence: the pickle/cPickle Up: Using Modules Previous: Information about your Python   Contents
Phil Spector 2003-11-12