Python:列表列表__getitem__

时间:2015-01-14 20:04:11

标签: python

我为连接4游戏创建了一个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?

我知道我需要定义__getitem__但是这种方法应该允许b[1][1]之类的语法?我已经看了some past questions,但我似乎无法找到我正在寻找的答案。

修改:也许以下是正确的做事方式?

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

3 个答案:

答案 0 :(得分:6)

您需要了解的基本事项是,对于b[1][2]这样的语法,有两个 __getitem__调用。首先,调用b.__getitem__(1),并返回一个对象。然后,调用returned_object.__getitem__(2)。因此,无论班级b是什么,都无法完全控制整个过程。

在上面的示例中,如果您将其定义为

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

然后b[1][2]将首先调用b.__getitem__(1),这将返回self.data[1],这将是一个列表。该列表还支持__getitem__,因此将调用下一个list.__getitem__(2)

如果你想控制两者那些,那么你需要定义另一个表示列的类,父类需要返回其中一个对象而不是原始列表,然后可以为自定义功能实现自己的__getitem__

其他选择是支持b[1,2]这样合法的语法 - 它会将b.__getitem__((1,2))称为(1,2)作为元组(您可以将任何放在那里)真的),但它并不那么自然。

答案 1 :(得分:3)

您可以返回子列表

所代表的row
def __getitem__(self, row):
    return self.data[row]

例如

>>> t = Test(2,5)
>>> t.data
[[' ', ' '],
 [' ', ' '],
 [' ', ' '],
 [' ', ' '],
 [' ', ' ']]

获得一行

>>> t[1]
[' ', ' ']

获取元素

>>> t[1][0]
' '

请注意,上面示例中的第二个操作[0]不需要您定义它,因为它只会从__getitem__调用list,因为它就是这样。< / p>

答案 2 :(得分:1)

只需返回行:

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