如何索引嵌套列表?
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
当在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