zoukankan      html  css  js  c++  java
  • Python之生成器(generator)和迭代器(Iterator)

    generator


    生成器generator:一边循环一边计算的机制。

    生成器是一个特殊的程序,可以被用于控制循环的迭代行为。python中的生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,可以使用next()函数和send()函数恢复生成器。

    生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用。但是,不同于一般函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这个消耗的内存数量将大大减小。因此,生成器看起来像是一个函数,但是表现得像迭代器。

    创建generator

    方法一:生成器表达式

    生成器表达式:返回一个对象,这个对象只有在需要的时候才产生结果。
    只要把一个列表生成式中的[]改为(),就创建一个generator。

    >>> list(x*x for x in range(5))
    [0, 1, 4, 9, 16]
    >>> list[x*x for x in range(5)]
      File "<stdin>", line 1
        list[x*x for x in range(5)]
                   ^
    SyntaxError: invalid syntax
    >>> #列表解析生成列表
    ... [ x**3 for x in range(5)]
    [0, 1, 8, 27, 64]
    >>> #生成器表达式
    ... ( x**3 for x in range(5))
    <generator object <genexpr> at 0x105d8ba50>
    >>> list( x**3 for x in range(5))
    [0, 1, 8, 27, 64]
    

    方法二:生成器函数

    也是用def定义,如果一个函数至少包含一个yield声明(当然它也可以包含其他yield或return),那么它就是一个generator.
    yield和return都会让函数返回一些东西,区别在于,return声明彻底结束一个函数,而yield声明是暂停函数,保存它的所有状态,并且后续被调用后会继续执行

    >> def my_gen():
    ...     n=1
    ...     print "first"
    ...     yield n
    ...     n+=1
    ...     print "second"
    ...     yield n
    ... 
    >>> for item in my_gen():
    ...     print item
    ... 
    first
    1
    second
    2
    >>
    

    一个迭代可以被写成生成器函数,也可以被写成生成器表达式,均支持自动和手动迭代。而且这些生成器只支持一个active迭代,也就是生成器的迭代器就是生成器本身。

    迭代器(迭代就是循环)


    可以直接作用于for循环的数据类型:

    • 集合数据类型,如list、tuple、dict、set、str
    • generator,包括生成器函数和表达式?
    • 这些可以直接作用于for循环对象的统称为可迭代对象:Iterable
    • 可以被next()函数调用并不断返回下一个值的对象成为迭代器:Iterator
    • 生成器都是Iterator对象,但list、dict、str虽然是Iterable(可迭代对象),却不是Iterator(迭代器)。
    • 把list、dict、str等Iterable变成Iterator可以使用iter()函数。

    Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

    小结

    • 凡是可作用于for循环的对象都是Iterable类型;
    • 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
    • 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
  • 相关阅读:
    洛谷 1842 [USACO05NOV]奶牛玩杂技【贪心】
    洛谷 1757 通天之分组背包【分组背包】
    洛谷 1330 封锁阳光大学
    洛谷 1019 单词接龙
    【模板】CDQ分治
    BZOJ 2734 洛谷 3226 [HNOI2012]集合选数【状压DP】【思维题】
    BZOJ 2457 [BeiJing2011]双端队列
    洛谷 2015 二叉苹果树
    牛客网 牛可乐发红包脱单ACM赛 C题 区区区间间间
    牛客网 牛可乐发红包脱单ACM赛 B题 小a的旅行计划
  • 原文地址:https://www.cnblogs.com/amyzhu/p/9241510.html
Copyright © 2011-2022 走看看