美文网首页
python语言之二:python迭代器

python语言之二:python迭代器

作者: Wu杰语 | 来源:发表于2018-06-10 15:57 被阅读0次

    python迭代器绝对可以说是python的一种语言机制,python语言基础上一大部分就是迭代器建立起来的,所以要学习它,并搞清楚迭代器的原理。

    本文从迭代器协议说起,然后介绍为何说迭代器是python语言的基础,最后介绍generator这种迭代器。

    python的迭代器协议

    先回忆一下常规的迭代器,C++和JAVA的迭代器是和容器紧紧结合在一起的,容器返回一个迭代器,然后就可以用iter++去访问迭代器了。为了访问容器,需要一个迭代器对象。
    python迭代器在概念上没有什么不同,和经典迭代器不同比较不同的是,python迭代器不一定非要和容器结合在一起,或者说不一定要代码来实现,很多工作都是由python解释器实现的。

    怎样称之为一个迭代器呢?支持python迭代器协议即可

    The iterator objects themselves are required to support the following two methods, which together form the *iterator protocol*:
    
    <dl class="method">
    
    <dt id="iterator.__iter__">`iterator.``__iter__`()</dt>
    
    <dd>
    
    Return the iterator object itself. This is required to allow both containers and iterators to be used with the [`for`](../reference/compound_stmts.html#for) and [`in`](../reference/expressions.html#in) statements..
    
    </dd>
    
    </dl>
    
    <dl class="method">
    
    <dt id="iterator.__next__">`iterator.``__next__`()</dt>
    
    <dd>
    
    Return the next item from the container. If there are no further items, raise the [`StopIteration`].
    
    </dd>
    
    </dl>
    
    

    这是python标准文档摘出来的,第一句话就说了,遵循迭代器协议,只要遵循这个协议,python解释器可以在for in语句支持迭代操作。

    迭代器是python语言的基础

    考虑一下python的循环语句,有两种循环控制,一种是for,一种是while,问题是为何要while呢?

    # for语句和迭代器紧密的结合在一起,可以说就是一个紧耦合,python的解释器把for和迭代器就栓在一起了
    for i in iter:
        dosomething
    # for搞不定的东西,例如说一直循环满足某个条件就退出
    while condition:
        dosomething
    

    这里按道理来讲,所有的while应该都能用for替代,怎么替代,就是按照语言本身的机制,实现condition的迭代器。但是还是用while比较直观。

    对比一下go语言就更加清楚了,go语言只有for,没有while

    // 一般型,对应于python for
    for init; condition;then {}
    // 条件型 对应于python while
    for conditon {}
    // 无限循环
    for {}
    

    go节省了一个while,但是重点不是节省了while,而是对比看python怎样把for和迭代器紧耦合在一起,成为语言的机制了。

    看到这里,再去学习python数据结构就比较有感觉了,随便查看一下python的复合结构list\tuple\string\set\dict,这些数据结构的操作是不是都和迭代器紧密的结合在一起呢?
    例如说可以用for in语句直接访问这些复合结构,解释器讲调用迭代器,把这些复合结构转迭代器,如果留意到这点,再去学习,你会很容易的对python更加深入一步。

    例如说:

    l = [1,2,3,4]
    for i in l:
        print(i)
    

    神奇的Generator

    generator在python中,比较神奇。我用我的理解来说一下,generator是基于python堆栈技术的迭代器。也就是说这是一个两层结构,第一层是迭代器,下面那层是基于堆栈的一个特殊实现。

    迭代器层

    首先看下面代码:

    def addOne(i):
        yield (i+1)
    

    python解释器在遇到yield关键字的时候,给它穿上迭代器的协议的新衣,在for in语句中就可以使用这个迭代器了。一个yield相当于一步next操作,注意,只是一步。

    堆栈实现层

    这个在segmentfault.com/a/1190000011330511中有详细的解释
    由于python迭代器是个程序,运行在堆中,所以不同于c, python迭代器的堆栈也在堆中,堆栈中的调用是指向堆的,所以在遇到yield的时候,python解释器就直接生产生成器,而不是执行代码。

    在这个层次,generator也有自己的操作,send,每次send就如同在操作next操作一样,所不同的是,send能传递给迭代器参数,当然第一个yield不能传递参数,第二个yield才可以。

    没有详细介绍过多的generator的细节,只是想简单说明一下,不要被generator迷惑,它的本质技术不是迭代器,只是被封装的符合迭代器操作,这样更符合人的认知。更强大的是很符合人类的思考方式,可以在代码中需要的地方插入yield产生generator,符合人类的思考方式才是generator最强大之处。

    总结

    python的迭代器是python语言的基础,只要符合迭代器协议,python的解释器就会帮你建立迭代器。从抽象的意义上,python使用迭代器作为界面,python的各种数据结构,包括神奇的generator,都是在迭代器界面下的一种迭代器的实现。

    相关文章

      网友评论

          本文标题:python语言之二:python迭代器

          本文链接:https://www.haomeiwen.com/subject/hdwfeftx.html