Python - is there a way to implement __getitem__ for multidimension array?

board[x][y] means board.__getitem__(x).__getitem__(y), so Board.__getitem__ has to return some kind of view that also supports __getitem__ and remembers x. This is a bit of work, but for some use cases (anything involving passing that view around) it's very convenient.

Another option is board[x, y], which means board.__getitem__((x, y)). Note that this passes a tuple to __getitem__, which you'll have to unpack manually (there is syntactic sugar for doing this in 2.x, but it's a bit obscure and also gone in 3.x, so you may want to avoid it in the interest of future porting work).


You might want to consider using this syntax:

board[(x, y)]

It's less pretty, but it allows you to have multidimensional arrays simply. Any number of dimensions in fact:

board[(1,6,34,2,6)]

By making board a defaultdict you can even have sparse dictionaries:

board[(1,6,34,2,6)]

>>> from collections import defaultdict
>>> board = defaultdict(lambda: 0)
>>> board[(1,6,8)] = 7
>>> board[(1,6,8)]
7
>>> board[(5,6,3)]
0

If you want something more advanced than that you probably want NumPy.


When you do board[x][y] you will cause two calls to __getitem__ because you are doing two separate accesses: [x] is one and [y] is another. There's no way to handle this directly in __getitem__; you'd have to have board[x] return some kind of sub-object that you could use [y] on to get the individual item. What you probably want is to have __getitem__ accept a tuple:

def __getitem__(self, tup):
    y, x = tup
    return self.board[y][x]

Then do:

board[x, y]

(Note that you have the order of x and y switched between __getitem__ and board[x][y] --- is that intentional?)