生成器详解(绝无仅有)

1,生成器的两种形式

  • 列表推导式的最外层[]换成()就变成了生成器
    In [15]: L = [ x*2 for x in range(5)]
    
    In [16]: L
    Out[16]: [0, 2, 4, 6, 8]
    
    In [17]: G = ( x*2 for x in range(5))
    
    In [18]: G
    Out[18]: <generator object <genexpr> at 0x7f626c132db0>
    
  • 函数的形式(函数内部只要含有yield就是一个生成器)
    In [30]: def fib(n):
       ....:     current = 0
       ....:     num1, num2 = 0, 1
       ....:     while current < n:
       ....:         num = num1
       ....:         num1, num2 = num2, num1+num2
       ....:         current += 1
       ....:         yield num
       ....:     return 'done'
    
  • 列表推导式和生成器的区别
    • 列表推导式占用空间,生成器节省空间

2, 生成器的取值方式

  • 通过next()函数进行取值
    • 因为生成器是特殊的迭代器,所以我们可以通过next()进行取值
  • 通过生成器对象.next()取值

3, 生成器的唤醒方式

  • next()函数进行唤醒
  • 通过生成器对象.send()方法,该方法可以向生成器内部传值
    • 接受该值的为yield左边的变量
    • 首次唤醒生成器不能使用send方法,因为没有变量去接受

4, 利用生成器完成斐波那契数列

  • 把函数中的return换成yield就好,当调用函数的时候,如果函数中有yield,不是调用函数,而是创建了一个生成器对象,我们可以通过for进行取值,所以生成器是一种特殊的迭代器

  • 从生成器取出值的第二种方式,通过next,通过next一次只能取出一个值,函数会暂停到返回值的地方 ,当再次调用的时候,程序继续执行!!

    In [30]: def fib(n):
    ....:     current = 0
    ....:     num1, num2 = 0, 1
    ....:     while current < n:
    ....:         num = num1
    ....:         num1, num2 = num2, num1+num2
    ....:         current += 1
    ....:         yield num
    ....:     return 'done'
    ....:
    
    In [31]: F = fib(5)
    
    In [32]: next(F)
    Out[32]: 1
    
    In [33]: next(F)
    Out[33]: 1
    
    In [34]: next(F)
    Out[34]: 2
    
    In [35]: next(F)
    Out[35]: 3
    
    In [36]: next(F)
    Out[36]: 5
    
    In [37]: next(F)
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-37-8c2b02b4361a> in <module>()
    ----> 1 next(F)
    
    StopIteration: done
    
    
  • 但是用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

    In [39]: g = fib(5)
    
    In [40]: while True:
       ....:     try:
       ....:         x = next(g)
       ....:         print("value:%d"%x)      
       ....:     except StopIteration as e:
       ....:         print("生成器返回值:%s"%e.value)
       ....:         break
       ....:     
    value:1
    value:1
    value:2
    value:3
    value:5
    生成器返回值:done
    
    In [41]:
    
    

5, 生成器总结

  • 生成器的两种形式(函数,列表推导式)
  • 生成器的两种唤醒方式(next函数, send方法)
  • 生成器两种唤醒方式的区别(send可以传值)
  • 在生成器内部如何接受return的返回值(通过捕获异常的方式获取, e.value)
  • send唤醒方式的注意点(首次唤醒不能使用send()方法)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值