【问题标题】:dual iterator in one python object一个python对象中的双重迭代器
【发布时间】:2009-06-22 03:12:19
【问题描述】:

在 python 中,我正在尝试编写一个支持两种不同迭代器的类。粗略地说,这个对象包含一个数据矩阵,我希望有两种不同类型的迭代器来支持行迭代和列迭代。

【问题讨论】:

    标签: python iterator


    【解决方案1】:

    dict 有几个迭代器生成方法——iterkeysitervaluesiteritems——你的类也应该如此。如果有一种“最自然”的迭代方式,为了方便和可读性,您还应该将其别名为 __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
    

    【讨论】:

    • 为什么不 (self.data[start : start + self.n] for start in xrange(0, self.n*self.n, self.n)) 来实现 iterrows?
    • 我只是更喜欢在方便的时候将 self.whatever 查找提升到循环之外——无论如何它们不应该在迭代过程中发生变化,但 Python 不会进行这种优化。但是肯定不止一种方法可以有效地迭代,我只是喜欢这里两种情况之间的对称性!
    【解决方案2】:

    这就是你要找的吗?

    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

    您还可以将实际值的迭代移动到类中。我不确定您是要遍历行/列(如图所示)还是行/列中的值

    【讨论】:

      【解决方案3】:

      好的,所以创建两个单独的方法,每个方法都是生成器。

      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要好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-11
      • 2020-06-03
      • 2011-05-17
      • 2012-07-23
      • 2010-09-17
      • 2019-09-15
      • 2011-03-02
      相关资源
      最近更新 更多