美文网首页PYTHON基础
15.生成器generator

15.生成器generator

作者: Stone_説 | 来源:发表于2020-12-21 00:44 被阅读0次

    目录:
    1.生成器介绍
    2.生成器举例
    3.生成器应用

    1.生成器介绍

    生成器指的是生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象
    生成器函数:

    函数体中包含yield语句的函数,返回生成器对象
    生成器对象,是一个可迭代对象,是一个迭代器
    生成器对象,是延迟计算,惰性求值的
    

    2.生成器举例

    普通的函数调用fn(),函数会立即执行完毕,但是生成器函数可以使用next函数多次执行

    >>> y = (i for i in range(5))
    >>> print(type(y))
    <class 'generator'>
    >>> print(next(y))
    0
    ...
    >>> print(next(y))
    4
    >>> print(next(y))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    

    生成器函数等价于生成器表达式,只不过生成器函数可以更加的复杂

    >>> def inc():
    ...     for i in range(5):
    ...             yield i
    >>> print(type(inc))
    <class 'function'>
    >>> print(type(inc()))
    <class 'generator'>
    >>> x = inc()
    >>> print(type(x))
    <class 'generator'>
    >>> print(next(x))
    0
    >>> for y in x:
    ...     print(y,'*')
    1 *
    2 *
    3 *
    4 *
    >>> for y in x:
    ...     print(y,'---')
    >>>
    

    在生成器函数中,使用多个yield语句,执行一次会暂停执行,把yield表达式的只返回
    再次执行会执行到下一个yield语句
    如果函数没有显示return语句,如果生成器函数执行到结尾,一样会抛出StopIteration异常

    return语句依然可以终止函数运行,但return语句的返回值不能被获取到 return会导致无法继续获取下一个值,抛出StopIteration异常

    >>> def gen():
    ...     print('line 1')
    ...     yield 1
    ...     print('line 2')
    ...     yield 2
    ...     print('line 3')
    ...     return 3
    >>> next(gen())
    line 1
    1
    >>> next(gen())
    line 1
    1
    >>> g = gen()
    >>> print(next(g))
    line 1
    1
    >>> print(next(g))
    line 2
    2
    >>> print(next(g))
    line 3
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration: 3
    >>> print(next(g,'End'))
    End
    

    3.生成器应用

    3.1无限循环

    正确写法

    >>> def counter():
    ...     i=0
    ...     while True:
    ...             i += 1
    ...             yield i
    >>> def inc(c):
    ...     return next(c)
    >>> c = counter()
    >>> print(inc(c))
    1
    >>> print(inc(c))
    2
    

    错误写法

    >>> def counter():
    ...     i = 0
    ...     while True:
    ...             i += 1
    ...             yield i
    >>> def inc():
    ...     c = counter()
    ...     return next(c) 
    >>> print(inc())
    1
    >>> print(inc())
    1
    
    3.2计数器

    不使用匿名函数

    >>> def inc():
    ...     def counter():
    ...             i = 0
    ...             while True:
    ...                     i += 1
    ...                     yield i
    ...     c = counter()
    ...     def _inc():
    ...             return next(c)
    ...     return _inc 
    >>> foo = inc()
    >>> print(foo())
    1
    >>> print(foo())
    2
    

    使用匿名函数

    >>> def inc():
    ...     def counter():
    ...             i = 0
    ...             while True:
    ...                     i += 1
    ...                     yield i
    ...     c = counter()
    ...     return lambda:next(c)
    >>> foo = inc()
    >>> print(foo())
    1
    >>> print(foo())
    2
    
    3.3处理递归问题

    原始代码

    >>> def fib():
    ...     x = 0
    ...     y = 1
    ...     while True:
    ...             yield y
    ...             x,y=y,x+y
    >>> foo=fib()
    >>> for _ in range(5):
    ...     print(next(foo))
    1
    1
    2
    3
    5
    >>> for _ in range(3):
    ...     next(foo)
    ...     print(next(foo))
    8
    13
    21
    34
    55
    89
    

    等效代码

    >>> pre = 0
    >>> cur = 1
    >>> print(pre,cur,end=' ')
    0 1 
    >>> def fib1(n,pre=0,cur=1):
    ...     pre,cur=cur,pre+cur
    ...     print(cur,end = ' ')
    ...     if n == 2:
    ...             return 
    ...     fib1(n-1,pre,cur)
    >>> fib1(13)
    1 2 3 5 8 13 21 34 55 89 144 233
    

    相关文章

      网友评论

        本文标题:15.生成器generator

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