【发布时间】:2009-06-22 03:12:19
【问题描述】:
在 python 中,我正在尝试编写一个支持两种不同迭代器的类。粗略地说,这个对象包含一个数据矩阵,我希望有两种不同类型的迭代器来支持行迭代和列迭代。
【问题讨论】:
在 python 中,我正在尝试编写一个支持两种不同迭代器的类。粗略地说,这个对象包含一个数据矩阵,我希望有两种不同类型的迭代器来支持行迭代和列迭代。
【问题讨论】:
dict 有几个迭代器生成方法——iterkeys、itervalues、iteritems——你的类也应该如此。如果有一种“最自然”的迭代方式,为了方便和可读性,您还应该将其别名为 __iter__(可能是 iterrows;当然总会有一些疑问,就像 @ 987654327@ 当我们设计它的迭代行为时,但合理的选择总比没有好)。
例如,假设您的矩阵是正方形的,被展平成一个行优先列表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
【讨论】:
这就是你要找的吗?
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。
您还可以将实际值的迭代移动到类中。我不确定您是要遍历行/列(如图所示)还是行/列中的值。
【讨论】:
好的,所以创建两个单独的方法,每个方法都是生成器。
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__。
【讨论】:
for row in matrix的能力是Python语法的重要组成部分,因此以某种方式定义iter总比没有iter要好。