一个Python对象中的双迭代器
在Python中,我想写一个类,这个类可以支持两种不同的迭代器。简单来说,这个对象里面包含了一组数据矩阵,我想要有两种不同的迭代器,分别用来按行和按列进行遍历。
3 个回答
2
好的,先创建两个单独的方法,每个方法都是一个生成器。
class Matrix(object):
def iter_rows(self):
for row in self.rows:
yield row
def iter_columns(self):
for column in self.columns:
yield column
你的 __iter__
方法可以默认遍历其中一个生成器,不过我建议干脆不写 __iter__
方法。
4
这就是你想要的东西吗?
class Matrix(object):
def __init__(self, rows):
self._rows = rows
def columns(self):
return zip(*self._rows)
def rows(self):
return self._rows
# Create a Matrix by providing rows.
m = Matrix([[1,2,3],
[4,5,6],
[7,8,9]])
# Iterate in row-major order.
for row in m.rows():
for value in row:
print value
# Iterate in column-major order.
for column in m.columns():
for value in column:
print value
如果你想要按需创建每一列,可以用 itertools.izip
来代替 zip
。
你也可以把实际值的遍历放到类里面。我不太确定你是想遍历行/列(像这样)还是想遍历行/列里面的值。
5
dict
(字典)有几种方法可以用来生成迭代器,比如 iterkeys
、itervalues
和 iteritems
。你的类也应该有类似的功能。如果有一种“最自然”的迭代方式,你应该把它也命名为 __iter__
,这样使用起来更方便、更易读(通常这可能是 iterrows
;当然,在设计 dict
的迭代行为时也会有一些疑问,但选择一个合理的方式总比没有好)。
举个例子,假设你的矩阵是方形的,数据被压缩成一个行优先的列表 self.data
,边长为 self.n
。那么:
def iterrows(self):
start = 0
n = self.n
data = self.data
while start < n*n:
stop = start + n
yield data[start:stop]
start = stop
def itercols(self):
start = 0
n = self.n
data = self.data
while start < n:
yield data[start::n]
start += 1
__iter__ = iterrows