[Tutor] filling 2d array with zeros

Steven D'Aprano steve at pearwood.info
Mon Sep 27 20:29:49 CEST 2010


On Tue, 28 Sep 2010 03:54:55 am Alex Hall wrote:
> Hi again everyone,
> I have a 2d array (I guess it is technically a list) which I want to
> fill with zeros. Later I will change some values, but any I do not
> change have to be zeros. I have two complex for loops, but I tried to
> scale things down to a couple list comprehensions and I broke things.
> What is wrong with the following line?
> self.am=[[(a,b) for a in range(len(self.lines)) a=0] for b in
> range(len(self.lines)) b=0]


Start with a single row, of n columns:

[0 for i in range(n)]  # the loop variable i is not used

Now all you need is to set n appropriately:

n = len(self.lines)
[0 for i in range(n)]


Is there an easier way? Yes, you don't even need a list comp:

[0]*n

Now make m rows of the same:

[ [0]*n for i in range(m) ]

And you are done.


You might be tempted to take a short-cut:

[ [0]*n ]*m

but this doesn't work as you expect. This is one of the rare Python 
gotchas -- it looks like it should work, but it doesn't behave like you 
might expect. Try it and see:

>>> a = [[0]*3]*4
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][1] = 2
>>> a
[[0, 2, 0], [0, 2, 0], [0, 2, 0], [0, 2, 0]]

What's going on here? It's a little complicated, so let's start with a 
simpler situation:

>>> b = [0, 0, 0]
>>> c = b  # c is an alias to the same list as b
>>> d = b  # so is d
>>> e = c  # and e
>>> b[0] = 3
>>> e
[3, 0, 0]

Because both b and e refer to the same list (not copies!) any change to 
b *must* also change e. It's like if Barack Obama gets a haircut, so 
does the current President of the USA, because they're the same person.

Now stick them in a list:

>>> a = [b, c, d, e]
>>> a
[[3, 0, 0], [3, 0, 0], [3, 0, 0], [3, 0, 0]]
>>> a[0][1] = 4
>>> a
[[3, 4, 0], [3, 4, 0], [3, 4, 0], [3, 4, 0]]

Modify one, modify them all, because in fact they are actually all the 
same list.

[ [0]*3 ]*4 behaves the same way. There's no problem in the inner list, 
but the outer list doesn't make four copies of [0,0,0], it has *one* 
list repeated four times. Modify one, modify them all.


-- 
Steven D'Aprano


More information about the Tutor mailing list