Python入门之迭代器

迭代器协议

  • 1.迭代器协议是指:python3中对象必须提供一个__next__()方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)
  • 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)
  • 3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象
迭代器(Iterator)概述
  • 迭代器是访问集合内元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素都被访问一遍后结束。
  • 迭代器不能回退,只能往前进行迭代。
  • 对于原生支持随机访问的数据结构(如tuple、list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值,这是后话)。但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式。
  • 迭代器的另一个优点就是它不要求你事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。这个特点被称为延迟计算或惰性求值(Lazy evaluation)。
  • 迭代器更大的功劳是提供了一个统一的访问集合的接口。只要是实现了__iter__()方法的对象,就可以使用迭代器进行访问。

 使用迭代器

  • 使用方法iter()或__iter__()获取迭代器对象
    >>> lst = range(1,10)
    >>> string = "chengd"
    >>> it1 = iter(lst)
    >>> it2 = lst.__iter__()
    >>> is1 = iter(string)
    >>> is2 = string.__iter__()
    >>> 
    >>> type(it1)
    <class 'range_iterator'>
    >>> type(it2)
    <class 'range_iterator'>
    >>> type(is1)
    <class 'str_iterator'>
    >>> type(is2)
    <class 'str_iterator'>

     

  • 使用迭代器的__next__()方法可以访问下一个元素:
    >>> it1.__next__()
    1
    >>> it1.__next__()
    2
    >>> it1.__next__()
    3
    >>> is1.__next__()
    'c'
    >>> is1.__next__()
    'h'
    >>> is1.__next__()
    'e'

     

  • 迭代器所有元素访问完毕后,再次使用__next__()方法会抛出StopIteration异常:
    >>> is2.__next__()
    'c'
    >>> is2.__next__()
    'h'
    >>> is2.__next__()
    'e'
    >>> is2.__next__()
    'n'
    >>> is2.__next__()
    'g'
    >>> is2.__next__()
    'd'
    >>> is2.__next__()
    Traceback (most recent call last):
      File "<pyshell#51>", line 1, in <module>
        is2.__next__()
    StopIteration

     

  • 对于迭代器访问抛出StopIteration异常问题;Python专门将关键字for用作了迭代器的语法糖。在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。上述代码可以写成如下的形式
    >>> string = "chengd"
    >>> is2 = iter(string)
    >>> for i in is2:
        print(i)
    
        
    c
    h
    e
    n
    g
    d

     

  • 迭代器的循环可以避开索引,但有时候我们还是需要索引来进行一些操作的;可以通过内建函数enumerate实现
    >>> string = "chengd"
    >>> is1 = iter(string)
    >>> for i,items in enumerate(is1,1):
        print(i,items)
    
        
    1 c
    2 h
    3 e
    4 n
    5 g
    6 d

     

*异常并不是非抛出不可的,不抛出该异常的迭代器将进行无限迭代,某些情况下这样的迭代器很有用。这种情况下,你需要自己判断元素并中止,否则就死循环了!

 

参考:Python函数式编程指南(三):迭代器

posted @ 2017-06-29 23:03  chengd  阅读(269)  评论(0)    收藏  举报