Python Multidimensional Array as a single List
Question: Sure, you can have nested lists to represent multidimensional arrays, but that
seems costly...

    
    
    [[0, 1], [2, 3]]
    

Is there some way to "encode" and "decode" the coordinate into a single
number, and use that number to lookup the corresponding element?

    
    
    [0, 1, 2, 3]
    

This needs to work with n-dimensions, not just two, and the best I could come
up with for encoding is:

    
    
    def getcellindex(self, location):
      cindex = 0
      cdrop = self.gridsize # where self.gridsize is the number of cells
      for index in xrange(self.numdimensions): # where self.numdimensions is the number of dimensions
        # where self.dimensions is a tuple of the different sizes of the corresponding dimension
        cdrop /= self.dimensions[index]
        cindex += cdrop * location[index]
      return cindex
    

There're probably ways to optimize this, but more importantly, how do I
reverse the process? And, does this function work?


Answer: Are you avoiding the obvious answer (i.e. `[[1, 2], [3, 4]]`) because of
concerns about its performance? If so and you're working with numberes, look
at [NumPy arrays](http://docs.scipy.org/doc/numpy/reference/arrays.html). The
best solution would be to not reinvent your own wheel.

**Edit:** If you do feel the need to do it your own way, you could follow a
[strided index
scheme](http://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html#internal-
memory-layout-of-an-ndarray) like NumPy, wihch might go something like this:

    
    
    import operator
    def product(lst):
        return reduce(operator.mul, lst, 1)
    
    class MyArray(object):
        def __init__(self, shape, initval):
            self.shape = shape
            self.strides = [ product(shape[i+1:]) for i in xrange(len(shape)) ]
            self.data = [initval] * product(shape)
    
        def getindex(self, loc):
            return sum([ x*y for x, y in zip(self.strides, loc) ])
    
        def getloc(self, index):
            loc = tuple()
            for s in self.strides:
                i = index // s
                index = index % s
                loc += (i,)
            return loc
    

To be used as:

    
    
    arr = MyArray((3, 2), 0)
    arr.getindex((2, 1))
      -> 5
    arr.getloc(5)
      -> (2, 1)
    

