Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: list of list __getitem__

Tags:

python

I've created a Board class for a connect 4 game that makes use of a list of lists. I'd like to have the object support indexing for both the rows and the columns of the board:

class Test:
    def __init__(self, cols, rows):
        self.cols = cols
        self.rows = rows
        self.data = [[' '] * cols for row in range(rows)]

    def __iter__(self):
        yield from self.data

    def __getitem__(self, row):
        pass
        # what should this be?

I know I need to define __getitem__ but what should this method be to allow syntax such as b[1][1]? I've taken a look at some past questions but I can't seem to find the answer I'm looking for.

Edit: maybe the following is the correct way to do things?

def __getitem__(self, row):
    return self.data[row]
like image 561
rookie Avatar asked Dec 20 '22 07:12

rookie


1 Answers

The fundamental thing you need to understand is that for syntax like b[1][2], there are two __getitem__ calls. First, b.__getitem__(1) is called, and that returns an object. Then, returned_object.__getitem__(2) is called. So, whatever class b is does NOT have full control over this whole process.

In your example above, if you defined it as

def __getitem__(self, row):
    return self.data[row]

then b[1][2] would first call b.__getitem__(1), which would return self.data[1], which would be a list. That list also supports __getitem__, and so next list.__getitem__(2) would be called.

If you want control over both of those, then you need to define another class that represents columns, the parent class would need to return one of those objects instead of the raw list, and then that one can implement its own __getitem__ for custom functionality.

Other choice is to support syntax like b[1,2] which is legal - it will call b.__getitem__((1,2)) with (1,2) as a tuple (you can put anything in there really), but it's not as natural.

like image 192
Corley Brigman Avatar answered Jan 02 '23 23:01

Corley Brigman