On 27 September 2010 22:00, Alex Hall <mehg...@gmail.com> wrote: > That makes sense. Basically, the * operator in this case acts as a > copying command. For simple data types this is fine, but throw in a > complex type, in this case a list (though I expect that any object > would do this) and you are just doing what Python does to copy > objects: copying the memory location, not making a deep copy and > getting a duplicate object.
It does not copy the object it makes multiple _references_ to the *same* object. So let's say you have a list [1,2,3] with variable a which is a list object containing 3 integer objects. Following Steven“s example you basically create a new list with 3 references to the first list with variable a. You could just as well have written it as [a,a,a] which is the same as [a] * 3. >>> a = [1,2,3] >>> b = [a,a,a] >>> b [[1, 2, 3], [1, 2, 3], [1, 2, 3]] >>> a[0] = 10 >>> a [10, 2, 3] >>> b [[10, 2, 3], [10, 2, 3], [10, 2, 3]] The next step is how do we create a real copy of the object instead of a new reference to the same object. There are multiple methods to create a copy. The easiest is using a slice. A slice returns (in this example) a *new* list with all the values. >>> b = [a[:],a[:],a[:]] >>> b [[1, 2, 3], [1, 2, 3], [1, 2, 3]] >>> a[0] = 10 >>> a [10, 2, 3] >>> b [[1, 2, 3], [1, 2, 3], [1, 2, 3]] >>> b[0][0] = 10 >>> b [[10, 2, 3], [1, 2, 3], [1, 2, 3]] Or use the copy modules to do the same, see help(copy) for more info. >>> import copy >>> a = [1,2,3] >>> b = [copy.copy(a), copy.copy(a), copy.copy(a)] >>> b [[1, 2, 3], [1, 2, 3], [1, 2, 3]] >>> a[0] = 10 >>> a [10, 2, 3] >>> b [[1, 2, 3], [1, 2, 3], [1, 2, 3]] >>> b[0][0] = 10 >>> b [[10, 2, 3], [1, 2, 3], [1, 2, 3]] copy.copy(a) is what we call a shallow copy. It only make a copy of the list object a. But what if list object a again contained 3 list objects? You then run into the same problem as before. >>> a = [[1,2],[3,4],[5,6]] >>> b = [copy.copy(a), copy.copy(a), copy.copy(a)] >>> b [[[1, 2], [3, 4], [5, 6]], [[1, 2], [3, 4], [5, 6]], [[1, 2], [3, 4], [5, 6]]] >>> a[0][0] = 10 >>> b [[[10, 2], [3, 4], [5, 6]], [[10, 2], [3, 4], [5, 6]], [[10, 2], [3, 4], [5, 6]]] For this you can use copy.deepcopy() which make sure you create a copy of each object (in this case lists). I found this was one of the most weird things I needed to understand about python. Hope this helps. Greets Sander _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor