Python-是否可以为多维数组实现__getitem __?

问题描述 投票:11回答:5

我想使用类似的东西:

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

但是很遗憾,我打电话给:

board[x][y]

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

python arrays python-2.7 numpy multidimensional-array
5个回答
15
投票

board[x][y]时,您将对__getitem__进行two调用,因为您要进行两个单独的访问:[x]是一个,而[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的顺序---是故意的吗?)


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更高级的东西。


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

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中也没有,所以您可能想要避免为了将来的移植工作而使用它。


0
投票

说b是类对象b = Board()。当您寻找B [0] [0] getitem通常不会起作用。相反,我们可以做的是将b的数据设置为一个新变量。

boardData = b.data

print(boardData [0] [0])

© www.soinside.com 2019 - 2024. All rights reserved.