Help, multidimensional list

C

Crawley

Im trying to create a list of lists and for some reason its not working:

class Tile:
_next = { 'n':None, 'ne':None, 'e':None, 'se':None, 's':None,
'sw':None, 'w':None, 'nw':None }


def blankGridCanvas( maxx, maxy ):
grid = []
for y in xrange( 0, maxy ):
yline = []
for x in xrange( 0, maxx ):
t = Tile()
if y != 0:
t._next[ 'n' ] = grid[ y - 1 ][ x ]
t._next[ 'n' ]._next[ 's' ] = t

yline.append( t )
grid.append( yline )

for y in xrange( 0, maxy ):
for x in xrange( 0, maxx ):
print grid[ x ][ y ], grid[ x ][ y ]._next
return grid

now by my reconing this should be a list of lists with each element being
an instance of Tile, and some references being manipulated to point to each
other. But strangly no, its actually a list of lists where each element is
the SAME instance of Tile, so I change one, i change them ALL!

Whats going on and how do I solve it?

Rich
 
C

Christopher Koppler

Im trying to create a list of lists and for some reason its not working:

class Tile:
_next = { 'n':None, 'ne':None, 'e':None, 'se':None, 's':None,
'sw':None, 'w':None, 'nw':None }


def blankGridCanvas( maxx, maxy ):
grid = []
for y in xrange( 0, maxy ):
yline = []
for x in xrange( 0, maxx ):
t = Tile()
if y != 0:
t._next[ 'n' ] = grid[ y - 1 ][ x ]
t._next[ 'n' ]._next[ 's' ] = t

yline.append( t )
grid.append( yline )

for y in xrange( 0, maxy ):
for x in xrange( 0, maxx ):
print grid[ x ][ y ], grid[ x ][ y ]._next
return grid

now by my reconing this should be a list of lists with each element being
an instance of Tile,

You only create a *class* Tile, and provide no way to create
*instances* of it - so much like with static variables in other
languages, you only have one 'instance' here. To be able to create
separate instances, you need a constructor in your class to
instantiate every instance, like so:

class Tile:
def __init__(self):
self._next = { 'n':None, 'ne':None, 'e':None, 'se':None,
's':None, 'sw':None, 'w':None, 'nw':None }


and some references being manipulated to point to each
other. But strangly no, its actually a list of lists where each element is
the SAME instance of Tile, so I change one, i change them ALL!

Whats going on and how do I solve it?

Any gurus around can certainly much better explain what's going on and
why...
 
T

Terry Reedy

Christopher Koppler said:
Im trying to create a list of lists and for some reason its not working:

class Tile:
_next = { 'n':None, 'ne':None, 'e':None, 'se':None, 's':None,
'sw':None, 'w':None, 'nw':None }


def blankGridCanvas( maxx, maxy ):
grid = []
for y in xrange( 0, maxy ):
yline = []
for x in xrange( 0, maxx ):
t = Tile()
if y != 0:
t._next[ 'n' ] = grid[ y - 1 ][ x ]
t._next[ 'n' ]._next[ 's' ] = t

yline.append( t )
grid.append( yline )

for y in xrange( 0, maxy ):
for x in xrange( 0, maxx ):
print grid[ x ][ y ], grid[ x ][ y ]._next
return grid

now by my reconing this should be a list of lists with each element being
an instance of Tile,

You only create a *class* Tile, and provide no way to create
*instances* of it

No, the line 't=Tile()' does create a separate Tile for each grid position.
However, there is only one class attribute shared by all instances.
- so much like with static variables in other
languages, you only have one 'instance' here. To be able to create
separate instances, you need a constructor in your class to
instantiate every instance, like so:

class Tile:
def __init__(self):
self._next = { 'n':None, 'ne':None, 'e':None, 'se':None,
's':None, 'sw':None, 'w':None, 'nw':None }

You do not need __init__ for separate instances, but do need it to give
each instance its own map.
and some references being manipulated to point to each

As stated above, you do have separate instances but only one map attached
to the class instead of a separate map for each instance. Koppler's
__init__ will fix this.

Terry J. Reedy
 
C

Christopher Koppler

Christopher Koppler said:
Im trying to create a list of lists and for some reason its not working:

class Tile:
_next = { 'n':None, 'ne':None, 'e':None, 'se':None, 's':None,
'sw':None, 'w':None, 'nw':None }

[snip some code]

now by my reconing this should be a list of lists with each element being
an instance of Tile,

You only create a *class* Tile, and provide no way to create
*instances* of it

No, the line 't=Tile()' does create a separate Tile for each grid position.
However, there is only one class attribute shared by all instances.

Yes, thanks for clearing that up. That is what I probably meant and
didn't know how to say. Too merry Xmas this year ;-)
You do not need __init__ for separate instances, but do need it to give
each instance its own map.

I think that's what I meant with the comparison to static variables,
but should have read static class attributes.
 

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

Forum statistics

Threads
474,173
Messages
2,570,939
Members
47,484
Latest member
JackRichard

Latest Threads

Top