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

rta7y2nd  于 12个月前  发布在  Python
关注(0)|答案(6)|浏览(96)

我想用这样的东西:

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

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

board[x][y]

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

n8ghc7c1

n8ghc7c11#

当你执行board[x][y]时,你将导致 * 两个 * 对__getitem__的调用,因为你正在执行两个单独的访问:[x]是一个,[y]是另一个。在__getitem__中没有办法直接处理这个问题;你必须让board[x]返回某种类型的子对象,你可以在上面使用[y]来获取单个项。你可能想要的是让__getitem__接受一个元组:

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

然后执行:

board[x, y]

(Note你把x和y的顺序在__getitem__board[x][y]之间切换了-这是故意的吗?)

flvtvl50

flvtvl502#

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

board[(x, y)]

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

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

通过将board设置为defaultdict,你甚至可以拥有稀疏字典:

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

kuhbmx9i

kuhbmx9i3#

board[x][y]意味着board.__getitem__(x).__getitem__(y),所以Board.__getitem__必须返回某种也支持__getitem__并记住x的视图。这是一个小工作,但对于某些用例(任何涉及传递视图的情况),它非常方便。
另一个选项是board[x, y],这意味着board.__getitem__((x, y))。请注意,这会将一个元组传递给__getitem__,您必须手动解包(在2.x中有语法糖来完成此操作,但它有点晦涩,在3.x中也没有,因此您可能希望避免它,以便将来进行移植工作)。

p3rjfoxz

p3rjfoxz4#

只要做:

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
mrphzbgm

mrphzbgm5#

我认为索引一个2D自定义对象可以通过状态保留来完成。
正如上面的帖子中提到的,2D索引到自定义对象将调用__getitem__()两次。如果__getitem__()可以记住它在第一次调用中返回了电路板的一行,那么它可以在第二次调用中返回列值。

def __getitem__(self, item):

    def get(id):
        # This is the first time get() is being called,
        # return the row indexed by item
        if not get.row:
            get.row = self.board[item]
            return get.row
        else:
        # This is the second time get() is called,
        # return the column in the row indexed by item
            return get.row[item]

    # Set the function attribute "row". 
    # This is used to remember if get() was called once before.
    get.row = None
    return get(item)
fruv7luv

fruv7luv6#

假设B是类对象B = Board()。当您正在寻找B[0][0]__getitem__通常不会工作。相反,我们可以将B的数据设置为一个新的变量。

boardData = b.data

print(boardData[0][0])

相关问题