########## Notes On Mutable Objects and Pointers ##################################################### # All data are stored in memory. a "pointer" is just a memory address. # Note the following phenomenon and consider it in depth: x = 1 y = x x = x+1 # At this point, x is 2 but y is still 1. Because x and y refer to different # memory locations. The statement y=x copied the contents of the x location # to a new location for y. # What if the values are not simply numerical values? A = [1,2,3] B = A A = [4,6,8] # At this point, A becomes [4,6,8] but B is still [1,2,3]. The situation is # the same as with the case of numerical values. The statement A=[4,6,8] # associates with A a new memory address that contains the array. But # B is still associated with the original memory location. In fact, # we can think of the values of A and B not as the arrays that they're assigned # to, but as *pointers*, that is, memory locations of these arrays. # Thus the statement B=A causes B and A to point to the same array. A # pointer is an indirect reference: an address of a location instead of the # location itself. # What can we infer from the above explanation? Consider the following: A = [1,2,3] B = A A[0] = 9 print B[0] # will print 9 # The key difference between this example and the one above is that the # statement A[0]=9 did NOT change A, it changed A[0]. 'A' is still pointing # to the same memory location, but the content of that location has changed. # At this point, where is B pointing to? Clearly it is pointing to the # same location as A. So then what do you expect B[0] to become?! # It's also been changed to 9! ### *** PLEASE REMEMBER: A[0]=9 does not change A: it changes the array ### *** that A points to. ######### There is another explanation to this phenomenon: arrays are mutable # objects. Suppose we used strings, which you know to be immutable: s = "abc" t = s s = "edf" # As you can see, because strings are immutable, I can't even construct the # example above. The statement s = "edf" does NOT change the original string # "abc": it merely associates s with a new string. The string itself is # not changed: the variable is assigned to a new string! ### When programming with arrays, it's best to keep in mind that array # variables (like A, B above) are pointers because of the mutable nature of # arrays. For example, suppose I wanted to create a copy of an array so # I can modify it WITHOUT affecting the original array. If that's my # intent then I better not do the following: A = [1,2,3] B = A # Because I haven't really copied the array at all, only assigned another # pointer (B) to point to the SAME array! To do what I intended, I need # to create an array from scratch, and individually copy over each value: def makecopy(A): # returns a copy of A in a different memory location B = len(A) * [0] # pre-allocate array of correct size i = 0 while i