References and Copies
When a program makes an assignment such as a = b, a new reference to b is created. For immutable objects such as numbers and strings, this assignment effectively creates a copy of b. However, the behavior is quite different for mutable objects such as lists and dictionaries. For example:
b = [1,2,3,4] a = b # a is a reference to b a[2] = -100 # Change an element in 'a' print b # Produces '[1, 2, -100, 4]'
Because a and b refer to the same object in this example, a change made to one of the variables is reflected in the other. To avoid this, you have to create a copy of an object rather than a new reference.
Two types of copy operations are applied to container objects such as lists and dictionaries: a shallow copy and a deep copy. A shallow copy creates a new object, but populates it with references to the items contained in the original object. For example:
b = [ 1, 2, [3,4] ] a = b[:] # Create a shallow copy of b. a.append(100) # Append element to a. print b # Produces '[1,2, [3,4]]'. b unchanged. a[2][0] = -100 # Modify an element of a. print b # Produces '[1,2, [-100,4]]'.
In this case, a and b are separate list objects, but the elements they contain are shared. Therefore, a modification to one of the elements of a also modifies an element of b, as shown.
A deep copy creates a new object and recursively copies all the objects it contains. There is no built-in function to create deep copies of objects. However, the copy.deepcopy() function in the standard library can be used, as shown in the following example:
import copy b = [1, 2, [3, 4] ] a = copy.deepcopy(b) a[2] = -100 print a # produces [1,2, -100, 4] print b # produces [1,2,3,4]