美文网首页
迭代器与生成器

迭代器与生成器

作者: 魔曦帝天 | 来源:发表于2019-10-31 08:47 被阅读0次

    迭代(iteration)与可迭代(iterable)

    迭代是一种操作;可迭代是对象的一种特性。
    
    我们可以从一个对象中,逐个地获取元素,那么我们就说这个对象是「可迭代的」。
    

    迭代器

    迭代器是一种对象
    迭代器抽象的是一个「数据流」,是只允许迭代一次的对象。对迭代器不断调用 next() 方法,则可以依次获取下一个元素;当迭代器中没有元素时,调用 next() 方法会抛出 StopIteration 异常。迭代器的 __iter__() 方法返回迭代器自身;因此迭代器也是可迭代的。
    

    迭代器协议(iterator protocol)

    Python 中的迭代器协议和 Python 中的 for 循环是紧密相连的。
    
    # iterator protocol and for loop
    for x in something:
        print(x)
    Python 处理 for 循环时,首先会调用内建函数 iter(something),它实际上会调用 something.__iter__(),返回 something 对应的迭代器。而后,for 循环会调用内建函数 next(),作用在迭代器上,获取迭代器的下一个元素,并赋值给 x。此后,Python 才开始执行循环体。
    

    for循环内部操作

    for循环中,会自动调用 iter()将我们要迭代的对象转化为可迭代对象,每次循环都会调用 .next() 方法获取新元素,当引发StopIteration错误的时候自动退出循环,这就for循环的内部操作。
    

    Python 中的顺序类型,都是可迭代的(list, tuple, string)。其余包括 dict, set, file 也是可迭代的。对于用户自己实现的类型,如果提供了 iter() 或者 getitem() 方法,那么该类的对象也是可迭代的。

    生成器、yield 表达式

    调用过程

    yield的核心在于冻结函数,一旦遇到,冻结这个函数;而return在于结束函数,一旦遇到,返回结果,函数整个退出,下次调用时重新开始执行。

    生成器就是每次调用的时候返回一个对象,而不是一次性在内存中创建,从而达到节约内存的作用。
    
    而生成器靠yield关键字实现,生成器的编写类似于函数,只不过将函数的return改成了yield:
    

    生成器函数(generator function)和生成器(generator)

    生成器函数是一种特殊的函数;生成器则是特殊的迭代器。
    
    如果一个函数包含 yield 表达式,那么它是一个生成器函数
    调用它会返回一个特殊的迭代器,称为生成器。
    
    def func():
        return 1
    
    def gen():
        yield 1
    
    print(type(func))   # <class 'function'>
    print(type(gen))    # <class 'function'>
    
    print(type(func())) # <class 'int'>
    print(type(gen()))  # <class 'generator'>
    
    生成器 gen 看起来和普通的函数没有太大区别。仅只是将 return 换成了 yield。
    用 type() 函数打印二者的类型也能发现,func 和 gen 都是函数。
    二者的返回值的类型就不同了。
    func() 是一个 int 类型的对象;而 gen() 则是一个迭代器对象。
    

    与普通函数的区别

    生成器函数被调用后,其函数体内的代码并不会立即执行,
    而是返回一个生成器(generator-iterator)。
    当返回的生成器调用成员方法时,相应的生成器函数中的代码才会执行
    

    相关文章

      网友评论

          本文标题:迭代器与生成器

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