如何索引嵌套列表?

How can I indexing nested lists?

当在class中遇到嵌套列表时(更具体地说,我应该称它为多元函数),我可以使用带有两个或更多参数的__getitem__方法吗?

我知道这不是 __getitem__ 的典型用法,我应该把它写成 class 的方法,但我真的想利用它的 [] 特性。

这真的一点也不反常; numpy 一直在做。 __getitem__ 接受一个参数;它可以是一个元组。您只需要自己解析元组。

class Indexer(object):
    def __init__(self, *args, **kwargs): 
        pass
    def __getitem__(self, item):
        if isinstance(item, tuple):
            # do special processing for tuples here
            print(item)
        # Everyone likes the number 3, so make sure to return an extra 3.
        return [item, 3]
i = Indexer()

# this will print (2, 3), and got_item will have the value [(2, 3), 3]
got_item = i[2,3]

# This will print [(2, 3), 3]
print(got_item)

显然 return [item, 3] 没有真正的理由,但它只是证明 __getitem__ 中的代码可以为所欲为。您可以 return 随心所欲。

每当 Python 解释器发现你索引了一些东西(如代码示例中的 i[2, 3] ),它做的第一件事就是用方括号之间的东西构建一个元组。您可以使用 dis 模块来检查这一点,该模块反汇编 python 代码以查看解释器真正在做什么:

import dis
dis.dis('a[b, c]')

  1           0 LOAD_NAME                0 (a)
              3 LOAD_NAME                1 (b)
              6 LOAD_NAME                2 (c)
              9 BUILD_TUPLE              2
             12 BINARY_SUBSCR
             13 RETURN_VALUE

如果您以前从未见过 dis 的输出,可能会有点困惑。重要的部分是它说 BUILD_TUPLE 之前它说 BINARY_SUBSCR.

这可能是太多的信息:重要的是你可以用 __getitem__.

做任何你想做的事

__getitem__ 接受任意数量的参数,因为它们被打包为一个元组。请参阅以下示例,其中 class 中的 嵌套列表存储在 _data 中并使用特定维度进行初始化。

class Table(object):
    def __init__(self, dimx, dimy, initialize=0):
        self._dimx = dimx
        self._dimy = dimy
        self._data = [[initialize] * self._dimx] * self._dimy

    def __getitem__(self, *args):
        idx = args[0]
        return self._data[idx[0]][idx[1]]

    def __setitem__(self, *args):
        idx = args[0]
        self._data[idx[0]][idx[1]] = args[1]

有了这个 class,您可以简单地执行以下操作:

t = Table(10, 1)
t[0, 1] = 'a'
print(t[0, 0])
print(t[0, 1])

... 它将产生:

0
a