Python - 有没有办法为多维数组实现__getitem__?

时间:2013-07-04 21:27:31

标签: python arrays python-2.7 numpy multidimensional-array

我想使用类似的东西:

class Board():
    ...
    def __getitem__(self, y, x):
        return self.board[y][x]

但不幸的是,当我打电话时:

board[x][y]

我得到: TypeError: __getitem__() takes exactly 3 arguments (2 given)

5 个答案:

答案 0 :(得分:13)

当您执行board[x][y]时,您将对__getitem__进行两次调用,因为您正在进行两次单独访问:[x]为1,[y]是另一个。在__getitem__中无法直接处理此问题;您必须让board[x]返回某种子对象,您可以使用[y]来获取单个项目。你可能想要的是让__getitem__接受一个元组:

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

然后做:

board[x, y]

(请注意,您在__getitem__board[x][y]之间切换了x和y的顺序---这是故意的吗?)

答案 1 :(得分:4)

您可能需要考虑使用以下语法:

board[(x, y)]

它不那么漂亮,但它允许你简单地拥有多维数组。事实上任何数量的维度:

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

通过将棋盘设为默认词,您甚至可以使用稀疏词典:

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

如果你想要比你想要更高级的东西NumPy

答案 2 :(得分:3)

只是做:

class Board():
    def __getitem__(self, x):
        return self.board[x]

因为当您致电b[x][y]时,它实际上会拨打__getitem__()两次,如下所示:

import numpy as np
b = Board()
b.board = np.random.random((3,3,3))
print (b[2][0]==(b[2])[0]).all()
#True

但最好的是继承np.ndarray,这样你就不必重新实现这个方法了:

class Board(np.ndarray):
    pass

答案 3 :(得分:2)

board[x][y]表示board.__getitem__(x).__getitem__(y),因此Board.__getitem__必须返回某种支持__getitem__的视图,并记住x。这是一些工作,但对于一些用例(涉及传递该视图的任何事情),它非常方便。

另一个选项是board[x, y],表示board.__getitem__((x, y))。请注意,这会将一个元组传递给__getitem__,你必须手动解压缩(在2.x中有这样做的语法糖,但它有点模糊,也在3.x中,所以你可能为了未来移植工作的利益而想避免它。)

答案 4 :(得分:-1)

说b是类对象b = Board()。当您寻找B[0][0] __getitem__通常无法正常工作。相反,我们可以做的是将b的数据设置为新变量。

boardData = b.data

print(boardData[0][0])