Python数据科学指南
上QQ阅读APP看书,第一时间看更新

1.8 使用迭代器

毫无疑问,对于数据科学的程序而言,数据是极其重要的输入。数据的大小是可变的,有些能装载到内存中,有些则不能。而记录访问架构也是随一种数据格式到另一种而变化。有趣的是,不同的算法处理数据时,需要的是可变长度的组块。例如,假如你在写一个随机梯度下降的算法,你希望在每个时间片传送5000条记录的数据块,如果你对如何访问数据、理解数据格式、依次传送数据、给调用者需要的数据等流程有着清晰的概念,那你才能成功。这样能让你写出清晰的代码。大多数时候,最有趣的部分是我们如何处理数据,而不是我们怎么访问这些数据。Python给我们提供了迭代器这种优雅的方式来处理所有这些需求。

1.8.1 准备工作

Python中的迭代器实现了一种迭代器模式,它让我们可以一个接一个地处理一个序列,但不需要真正实现整个序列。

1.8.2 操作方法

我们来创建一个简单的迭代器,叫作“简单计数器”,用一些代码演示了怎样高效地使用迭代器。

        # 1.写一个简单的迭代器
        class  SimpleCounter(object):
            def __init__(self, start, end):
              self.current  =  start
              self.end  =  end
            def __iter__(self):
              'Returns  itself  as  an  iterator  object'
              return  self
            def  next(self)  :
              'Returns  the  next  value  till  current  is  lower  than  end'
              if  self.current  >  self.end:
                  raise  StopIteration
              else:
                  self.current  +=  1
                  return  self.current  -  1
        # 2.现在来访问这个迭代器
        c  =  SimpleCounter(1,3)
        print  c.next()
        print  c.next()
        print  c.next()
        print  c.next()
        # 3.另外一种访问方式
        for  entry  in  iter(c):
            print  entry

1.8.3 工作原理

在第1步中,我们定义了一个名为SimpleCounter的类,构造函数_init_有两个参数:起始和结束,来定义序列的开始和结束。请注意_iter_和next这两个方法,在Python中想要成为一个迭代器的对象必须都支持这两个函数。_iter_返回整个类对象作为一个迭代器对象,next方法返回迭代器里的下一个值。

如第2步所示,我们可以使用next()函数访问迭代器中的连续元素。Python也提供了一个方便的函数iter(),它能用来在循环体中循序访问元素,如第3步所示。它在内部实现中使用了next函数。

请注意,一个迭代器对象只能被使用一次。运行上面的代码之后,如果我们仍要像下面这样访问迭代器。

        print  next(c)

系统会抛出一个StopIteration异常。在序列已经到尾部的时候再调用c.next()会触发一个StopIteration异常。

            raise  StopIteration
        StopIteration
        >>>

iter()函数会处理这个异常,当数据访问完成的时候退出循环。

1.8.4 更多内容

再看另一个迭代器的示例,我们需要在程序中访问一个非常大的文件,不过,在代码里,我们每次只访问一行,直到读完整个文件。

        f = open(some_file_of_interest)
        for  l  in  iter(f):
        print  l
        f.close()

在Python里,一个文件对象就是一个迭代器,它支持iter()和next()函数。因此,我们每次只处理一行数据,而不是将全部文件加载到内存中。

迭代器给了你自由,你可以让你的应用程序自己定义访问你的数据源的方式。

下面的链接提供了Python中多种多样的迭代器使用方法的信息,如无限迭代器itertools中的count()、cycle()以及repeat()等。

https://docs.python.org/2/library/itertools.html#itertools.cycle