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

生成器&迭代器

作者: syp_xp | 来源:发表于2017-05-28 14:18 被阅读21次

    生成器

    只要把一个列表生成式的[]改成(),就创建了一个generator,生成器的意义在于一边循环一遍计算的机制,节省大量的内存空间,generator保存的是算法,调用next方法计算下一个元素的值,直到最后抛出StopIteration异常

    >>> L = [x * x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g = (x * x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x1022ef630>
    
    >>> next(g)
    0
    >>> next(g)
    1
    

    生成器是支持for循环的可迭代对象

    >>> g = (x * x for x in range(10))
    >>> for n in g:
    ...     print(n)
    

    如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
        return 'done'
    
    >>> f = fib(6)
    >>> f
    <generator object fib at 0x104feaaa0>
    

    generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

    def odd():
        print('step 1')
        yield 1
        print('step 2')
        yield(3)
        print('step 3')
        yield(5)
    >>> o = odd()
    >>> next(o)
    step 1
    1
    >>> next(o)
    step 2
    3
    >>> next(o)
    step 3
    5
    >>> next(o)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    

    把函数改成generator后,也成为支持for循环遍历的对象


    迭代器

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

    • 一类是集合数据类型,如list、tuple、dict、set、str等;

    • 一类是generator,包括生成器和带yield的generator function。

    这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。可以使用isinstance()判断一个对象是否是Iterable对象

    >>> from collections import Iterable
    >>> isinstance([], Iterable)
    True
    >>> isinstance({}, Iterable)
    True
    >>> isinstance('abc', Iterable)
    True
    >>> isinstance((x for x in range(10)), Iterable)
    True
    >>> isinstance(100, Iterable)
    False
    

    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。可以使用isinstance()判断一个对象是否是Iterator对象:

    >>> from collections import Iterator
    >>> isinstance((x for x in range(10)), Iterator)
    True
    >>> isinstance([], Iterator)
    False
    >>> isinstance({}, Iterator)
    False
    >>> isinstance('abc', Iterator)
    False
    

    生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。把list、dict、str等Iterable变成Iterator可以使用iter()函数:

    >>> isinstance(iter([]), Iterator)
    True
    >>> isinstance(iter('abc'), Iterator)
    True
    

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

    相关文章

      网友评论

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

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