zoukankan      html  css  js  c++  java
  • python中迭代器和生成器

    1 l=[1,2,3,4]
    2  
    3 for n in l:
    4     print n

    在看上面这段代码的时候,我们没有显式的控制列表的偏移量,就可以自动的遍历了整个列表对象。那么for 语句是怎么来遍历列表l的呢?要回答这个问题,我们必须首先来看一下迭代器相关的知识。

    1.迭代器

    迭代器对象要求支持迭代器协议,所谓支持迭代器协议就是对象包含__iter__()和next()方法。其中__iter__()方法返回迭代器对象自己;next()方法返回下一个前进到下一个结果,在结尾时引发StopIteration异常。

    列表不是迭代器对象,但是列表通过__iter__()可以得到一个迭代器对象来遍历整个列表的内容,像列表这样的序列对象都属于这种情况;与序列不同,文件对象本身就是一种迭代器对象。

     
    1 l=[1,2,3,4]
    2 f=open('test.c','r')
    3  
    4 iter(l) == l
    5 Out[131]: False
    6  
    7 iter (f)== f
    8 Out[132]: True

    一个迭代器的例子(来源:python tutorial)

     1 class Reverse:
     2     """Iterator for looping over a sequence backwards."""
     3     def __init__(self, data):
     4         self.data = data
     5         self.index = len(data)
     6     def __iter__(self):
     7         return self
     8     def next(self):
     9         if self.index == 0:
    10             raise StopIteration
    11         self.index = self.index - 1
    12         return self.data[self.index]

    2.生成器

    生成器使python可以很容易的支持迭代协议。生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yeild一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。

    一个生成器的例子(来源:python tutorial)

    1 def reverse(data):
    2     for index in range(len(data)-1, -1, -1):
    3         yield data[index]

    3.for语句如何工作

    在我们最前面的遍历列表的for语句中,for使用了列表支持迭代器的性质,可以每次通过调用迭代器的next()方法,来遍历到列表中的值,直到遇到StopIteration的异常。

    4.注意的问题:

    1. 像列表这种序列类型的对象,我们可以通过iter()来产生多个迭代器,在迭代的过程中各个迭代器相互对立;但是迭代器对象没法通过iter()方法来产生多个不同的迭代器,它们都指向了自身,所以没法独立使用。

    参考: python tutorial, stackoverflow

  • 相关阅读:
    CentOS中rpm和yum到底有什么区别?
    Anaconda是个什么东东?
    Hadoop入门学习整理(三)
    Hadoop入门学习整理(二)
    CentOS6.10下安装MongoDB和Redis
    Linux 系统中环境变量/etc/profile、/etc/bashrc、~/.bashrc的区别
    一些想法
    时间
    周末
    条件
  • 原文地址:https://www.cnblogs.com/micky-zhou/p/3453227.html
Copyright © 2011-2022 走看看