一般来说,如果你有一个二维数据结构,它是两个容器的组合——一个列表列表,或者一个字典字典。如果您想制作一个集合但要在两个维度上工作怎么办?
代替:
collection[y][x]
做:
collection[x,y]
我知道这是可能的,因为该PIL
Image.load
函数返回一个以这种方式工作的对象。
一般来说,如果你有一个二维数据结构,它是两个容器的组合——一个列表列表,或者一个字典字典。如果您想制作一个集合但要在两个维度上工作怎么办?
代替:
collection[y][x]
做:
collection[x,y]
我知道这是可能的,因为该PIL
Image.load
函数返回一个以这种方式工作的对象。
关键是要了解 Python 如何进行索引 -__getitem__
当您尝试使用方括号对其进行索引时,它会调用对象的方法[]
。感谢这个答案为我指明了正确的方向:创建一个可以用方括号访问的python对象
当您在方括号中使用一对索引时,将__getitem__
使用参数的元组调用该方法key
。
这是一个简单的演示类,当给定二维索引时,它只是将整数索引返回到一维列表中。
class xy(object):
def __init__(self, width):
self._width = width
def __getitem__(self, key):
return key[1] * self._width + key[0]
>>> test = xy(100)
>>> test[1, 2]
201
>>> test[22, 33]
3322
当分配给方括号中的索引时,还会使用一种伴随__setitem__
方法。
使用numpy数组。
如果你有一个普通的 Python 数组,你可以把它变成一个 numpy 数组并像你描述的那样访问它的元素:
a = [[1,2,3],[4,5,6],[7,8,9]]
A = numpy.array(a)
print A[1,1]
将打印:
5
另一个例子:
A = numpy.zeros((3, 3))
for i in range(3):
for j in range(3):
A[i,j] = i*j
print A
会给你:
[[ 0. 0. 0.]
[ 0. 1. 2.]
[ 0. 2. 4.]]
我在 python 邮件列表中找到了这个食谱。有了它,您可以使用索引迭代器访问容器的元素。如果您需要使用container[index_1, index_2]
符号,可以使用 Mark 帖子中概述的方法轻松调整。
>>> from operator import getitem
>>> from functools import reduce
>>> l = [1,[2,[3,4]]]
>>> print(reduce(getitem, [1,1,1], l))
4
这是我适应container[index_1, index_2]
符号的python邮件列表中建议的另一种方法。
class FlatIndex(object):
def __init__(self, l):
self.l = l
def __getitem__(self, key):
def nested(l, indexes):
if len(indexes) == 1:
return l[indexes[0]]
else:
return nested(l[indexes[0]], indexes[1:])
return nested(self.l, key)
>>> l = [1,[2,[3,4,[5,6]]]]
>>> a = FlatIndex(l)
>>> print(a[1,1,2,1])
6