Newbiequestion about lists and arrays....

M

Michael

Hi pythonians! (or whatever you call yourselfs...)

I would like to use an multidimensional matrix (3D or more) with
numbers (int:s and float:s). Could i use lists or arrays? How can i
retrieve a single element out of a list thats already in an other list
thats already in an other list (and so on...)

An example...

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



for this code example, how do i assign 888 to only one element (for
example, the element in the middle) in the matrix and not to the three
elements shown below?
888
[[[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]]]
Why does:

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

and

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

print out the same result?

Helping bitteplease.

/Michael
 
E

Erik Max Francis

Michael said:
I would like to use an multidimensional matrix (3D or more) with
numbers (int:s and float:s). Could i use lists or arrays? How can i
retrieve a single element out of a list thats already in an other list
thats already in an other list (and so on...)

It's because Python doesn't have copy semantics. You're building a list
of lists of lists, some of whose elements are references to the same
list.

To ensure that these lists are all distinct objects, and thus giving you
the expected behavior, don't use references to previous objects; create
new ones instead:
.... xs = []
.... for y in range(3):
.... ys = []
.... for z in range(3):
.... ys.append([1, 2, 3])
.... xs.append(ys)
.... c.append(xs)
.... [[[[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]], [[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]]],
[[[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]]]
[[[[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]], [[[1, 2, 3], [1, 2, 3], [1, 2, 3]],
[[1, 2, 3], 888, [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]]], [[[1,
2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2, 3], [1, 2, 3], [1, 2, 3]], [[1, 2,
3], [1, 2, 3], [1, 2, 3]]]]

There are other ways to do the job, of course, involing say list
comprehensions.
 
S

Sean Ross

[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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top