【问题标题】:Python: list of list __getitem__Python:列表 __getitem__ 的列表
【发布时间】:2015-01-14 20:04:11
【问题描述】:

我为使用列表列表的 connect 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]

【问题讨论】:

  • b[1][1] 是两个__getitem__ 调用,一个用于b[1],另一个调用__getitem__ 的结果。您的列表列表无法控制它们的作用。最简单的事情是让你的__getitem__ 接受一个元组,这样你就可以做b[1, 1]

标签: python


【解决方案1】:

您需要了解的基本内容是,对于像 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)

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

其他选择是支持像 b[1,2] 这样合法的语法 - 它会调用 b.__getitem__((1,2))(1,2) 作为一个元组(你可以把 anything 放在那里),但它不是很自然。

【讨论】:

  • 您不能使用@classmethod 装饰器并通过课程吗?然后你可以返回同一个类的另一个实例。
  • 好吧,如果你使用@classmethod,那么它只能在函数中使用类(而不是实例)变量,并且类的所有实例都会得到相同的结果——可能不是你想要的.但是您走在正确的轨道上-您可以在一个类上使用__getitem__(这不是@classmethod,只是一个常规描述符),然后创建同一类的另一个实例。例如,在etree.Elements 中,调用element[0] 将返回另一个Element,它是第一个孩子,并且可以嵌套任意深度。
【解决方案2】:

您可以返回由子列表表示的row

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

例如

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

获取一行

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

获取元素

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

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

【讨论】:

    【解决方案3】:

    只返回行:

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

    【讨论】:

      猜你喜欢
      • 2013-11-30
      • 1970-01-01
      • 2020-12-07
      • 1970-01-01
      • 2021-04-01
      • 2012-07-14
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多