Arrays, or somethings similar.

I did a search but was unable to find an exact answer, so I hope to ask anyone here that might know the answer.

I want an array (or similar variable storage method) that can be multi-dimensional. IE.

nameArray = [x,y]

This would allow me to be like;

nameArray[1,1] = Bob
nameArray[1,2] = Pilot

nameArray[2,1] = Jeff
nameArray[2,2] = Engineer

The objective is that I would be able to store information about a single person under an x, then (under multi-dimensional) in the y I could put data about them.

I don’t use name1=Jeff, name2=Bob, and such because there would be an unknown number of these names (specified by a user, perhaps).

And I can’t seem to get Array to work (I’m using code I’ve found via google, and used in other languages).

So, anyone know a method of multi-dimensional storage?

Yeah, Python can do this. It’s set up a little differently than other languages you’ve probably seen.

I’ve copied some code here. This piece of code creates a grid of x,y coordinates. Each coordinate then has values assigned to it. I’m using it to store information about the land at that part of the grid. In the program it stores values for elevation, water content, soil and whether or not a plant is on that spot. It should be useful for the type of thing you’re trying to accomplish.

def creategrid(self):
		self.grid = []
		for x in range(128):
			self.grid.append([]) #creates a list of lists 2D
			for y in range(128):
				self.grid[x].append([]) #creates a vertical list for each x,y list location.
				ele = self.mHeightFieldTesselator.getElevation(x,y)
				self.grid[x][y].append(ele)   #This spot is '0' in self.grid[x][y][0] 
				self.grid[x][y].append(0)    #This spot is '1' in self.grid[x][y][1]
				w = random.random()*10
				self.grid[x][y].append(w)   #Water spot

To retrieve data:

value = self.grid[x][y][V]

where “V” is the number of the value at that grid location. For example when V is 0, I’m talking about elevation, when V is 1 I’m talking about whether a plant can be placed there, when V is 2 I’m talking about amount of water at that spot.

Hope this helps.

Another way which can work if you know how big you need all dimensions to be in advance is to use a single array but with implicit dimensional indexing.

Say you have three dimensions x, y and z, and these dimensions each have lengths a, b, c. The total storage needed is a * b * c, so you just create one array (I’ll call it a) of that size. Then you access the element a[x][y][z] using

a[z * a * b + y * a + x]

Other formulas can work here; this is what I’ve used in the past for 3D arrays, with Z indexing a 2D grid, y indexing a row in that grid, and x indexing a single element in that row.

If this gets to tedious you can make a setter and accessor function that “flattens” the index.

Yet another way would be a dictionary using tuples as keys. This works kind of like a sparse array. Only the values you’ve set are stored, the others don’t exist and therefore you have to be careful about handling requests for unset values. Also, nothing is stopping your from using arbitrarily long tuples of arbitrary data, so if you want it to be meaningful you’d probably be best served by encapsulating access to the dictionary via a class.

Like this, for instance.

class Sparse3DArray:
    def __init__(self, default = 0.0):
        self._data = {}
        self.default = default #value to be returned when querying an empty value
    def _check(self, item):
        if len(item) != 3:
            raise KeyError('This class only handles 3D coords')
        x, y, z = map(int,item) #this'll raise an exception if any of the values cannot be converted to int
        return x, y, z
    def __getitem__(self, item):
        key = self._check(item)
        if self._data.has_key(key):
            return self._data[key]
        else:
            return self.default
    def __setitem__(self, item, val):
        key = self._check(item)
        self._data[key] = val

You can remove the _check method if you don’t care about encapsulation.

And you’d use it like this:

array = Sparse3DArray()
array[1,2,3] = 5.0
print array[1,2,3], array[500, 0, 5]
> 5.0 0.0

Another (cheap) one:

def make2DList( dimX, dimY ):
    return [ [None,] * dimY for x in range( dimX ) ]

a = make2DList( 10, 6 )
a[0][0] = 'Bob'
a[0][1] = 'Pilot'

Perhaps you want to create some “struct” for holding the person information, with explicit semantics for your y-dim, e.g. like this:

class Person:
   def __init__( self ):
        self.name = ''
        self.vacation = ''

personList = [ ]

p = Person( )
p.name = 'Bob'
p.vacation = 'Pilot'

personList.append( p )

Ahh, thankyou all very much. I’ll give each of your methods a shot, and see how it all works out!

I do enjoy using Python, it’s quite convenient in many ways, but there are still many particulars about it I’m catching on to. So, yet again, thanks for the help!

After reading your first post again more carefully I have to second enn0x’s last recommendation. Using a Person class to model the data you want to store is definitely the best choice here. It’ll make your code that much more readable, and therefore easier to maintain.