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?)