[Tutor] filling 2d array with zeros

Sander Sweers sander.sweers at gmail.com
Mon Sep 27 23:15:20 CEST 2010


On 27 September 2010 22:00, Alex Hall <mehgcap at 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


More information about the Tutor mailing list