populating a doubly-subscripted array

Mark Wooding mdw at distorted.org.uk
Tue Nov 9 00:28:11 CET 2010


ghw at accutrol.com writes:

> What am I missing?  I am using Python 3.1.2.
>
> ff = [[0.0]*5]*5
> ff                        #(lists 5x5 array of 0.0)
> for i in range(5):
>   for j in range(3):
>     ff[i][j] = i*10+j
>     print (i,j,ff[i][j])  # correctly prints ff array values
>
> ff                        # try this and see what happens!
>
> result of third print of ff
> [[40, 41, 42, 0.0, 0.0], [40, 41, 42, 0.0, 0.0], 
> [40, 41, 42, 0.0, 0.0], [40, 41, 42, 0.0, 0.0], 
> [40, 41, 42, 0.0, 0.0]]
>
> Obviously there is something missing in my understanding of 
> how array values are populated.  Why do all "rows" get 
> populated with the same set of values (40, 41, 42)?  

[I suppose that the trailing 0.0 entries aren't in question: they're
because the individual rows have width 5 -- from `[0.0]*5' -- but only
the first three items of each is initialzed -- because j iterates only
over range(3).]

So, why do they all come out the same?  The answer is because in fact
there are only two lists involved.  You probably thought that you were
building something like the thing on the left.  In fact, you have the
thing on the right.  (Try to forgive the rubbish ASCII art.)

        .--.    .--.--.--.--.--.        .--.
        | ----->|  |  |  |  |  |        | --.
        |__|    `--^--^--^--^--'        |__| \
        |  |    .--.--.--.--.--.        |  |  \
        | ----->|  |  |  |  |  |        | ---. \
        |__|    `--^--^--^--^--'        |__|  \v 
        |  |    .--.--.--.--.--.        |  |   \.--.--.--.--.--.
        | ----->|  |  |  |  |  |        | ----->|  |  |  |  |  |
        |__|    `--^--^--^--^--'        |__|   /`--^--^--^--^--'
        |  |    .--.--.--.--.--.        |  | /  ^
        | ----->|  |  |  |  |  |        | --'  /
        |__|    `--^--^--^--^--'        |__|  /
        |  |    .--.--.--.--.--.        |  | /
        | ----->|  |  |  |  |  |        | --'
        `--'    `--^--^--^--^--'        `--'

What [x] * n does is make a list, whose length is n, and all of whose
entries are precisely the value x.  If x itself is a list, then you get
an outer list all of whose entries are the /same/ inner list -- not
copies of it.  So when you appear to change entries in one of the inner
lists, all the other inner lists seem to change too -- because they're
actually the same list.

-- [mdw]



More information about the Python-list mailing list