Newbiequestion about lists and arrays....

Sean Ross sross at connectmail.carleton.ca
Sat Sep 6 18:34:27 EDT 2003


"Michael" <holmboe at kth.se> wrote in message
news:9193c0d1.0309061320.a0f430f at posting.google.com...

[snip]

> c=[1]*3
> for y in range(3):
>         for x in range(3):
>
>             c[x]=[1,2,3]
>         p[y]=c
>
> p[1][1][1]=888
> print p[1][1][1]
> print p

[snip]

> Why does:
>
> p[0][1][1]=888
>
> and
>
> p[1][1][1]=888
>
> print out the same result?


Hi.
The problem is with "p[y] = c". This line binds p[y] to whatever c is bound
to.

c
    \
     [[1,2,3], [1,2,3], [1,2,3]]
    /
p[y]

But, then, you've done this for all p[y], 0<=y<3, so

c
    \
     [[1,2,3], [1,2,3], [1,2,3]]
    /            |             |
p[0]       p[1]        p[2]


Now you modify p[1][1][1]:

p[1][1][1] = 888

with this result:

c
    \
     [[1,2,3], [1,888,3], [1,2,3]]
    /            |             |
p[0]       p[1]        p[2]


Thus, p, which is [p[0], p[1], p[2]], looks like

[[[1, 2, 3], [1, 888, 3], [1, 2, 3]],
 [[1, 2, 3], [1, 888, 3], [1, 2, 3]],
 [[1, 2, 3], [1, 888, 3], [1, 2, 3]]]

Which is not what you wanted. To avoid this, you need only change

p[y] = c

to

p[y] = c[:]


c[:] creates a copy of whatever c was bound to. p[y] is then bound to that
copy.

c
    \
     [[1,2,3], [1,2,3], [1,2,3]]   # original

     [[1,2,3], [1,2,3], [1,2,3]]    # copy (c[:])
    /
p[y]

This happens for each y, 0<=y<3, so

c
    \
     [[1,2,3], [1,2,3], [1,2,3]]   # original

     [[1,2,3], [1,2,3], [1,2,3]]    # copy (c[:])
    /
p[0]

     [[1,2,3], [1,2,3], [1,2,3]]    # copy (c[:])
    /
p[1]

     [[1,2,3], [1,2,3], [1,2,3]]    # copy (c[:])
    /
p[2]

Now, when you do

p[1][1][1] = 888

The result is

c
    \
     [[1,2,3], [1,2,3], [1,2,3]]

     [[1,2,3], [1,2,3], [1,2,3]]
    /
p[0]

     [[1,2,3], [1,888,3], [1,2,3]]
    /
p[1]

     [[1,2,3], [1,2,3], [1,2,3]]
    /
p[2]

And, thus, p, which is [p[0], p[1], p[2]], looks like:

[[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
 [[1, 2, 3], [1, 888, 3], [1, 2, 3]],
 [[1, 2, 3], [1, 2, 3], [1, 2, 3]]]

Which is what you were looking for.


Or, you could just build 'p' using a list comprehension:

>>> from pprint import pprint as puts
>>> p = [[[1,2,3] for y in range(3)] for x in range(3)]
>>> p[1][1][1] = 888
>>> puts(p)
[[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
 [[1, 2, 3], [1, 888, 3], [1, 2, 3]],
 [[1, 2, 3], [1, 2, 3], [1, 2, 3]]]

Which is also what you were looking for.

HTH
Sean
















More information about the Python-list mailing list