简单的yield用法

浅谈一下python yield的使用,最近在程序中很经常遇到这个关键词。在python中带有yield的函数称为生成器。可以把yield和return进行类比。但是它的用法有区别,下面简单看下效果。

def fab(max):
    n, a, b = 0, 0 ,1
    while n < max:
        yield b
        a, b = b, a+b
        n = n+1

for n in fab(5):
    print(n)

1
1
2
3
5

现在分析下,这个过程。yield的作用是将一个函数变成一个生成器,调用fab(5)不会执行fab这个函数,而是返回一个iteration对象。在for循环执行时,每次循环都会执行fab函数内部的代码,执行到yield b时,fab函数就会返回一个迭代值,下次迭代开始时,代码从yield b的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇见yield。

下面使用next()方法观察一下执行流程。

f = fab(5)
next(f)
1
next(f)
1
next(f)
2
next(f)
3
next(f)
5
next(f)
---------------------------------------------------------------------------

StopIteration                             Traceback (most recent call last)

<ipython-input-9-aff1dd02a623> in <module>
----> 1 next(f)


StopIteration: 

当函数执行结束,生成器会抛出异常,表示迭代完成。可以使用next()对其进行调用,在for循环中会自动调用next,使用yield就是把一个函数改写为生成器,使其有迭代能力。next就相当于下一步生成哪个数,这一次的next开始的地方就是接着上一次的next停止的地方执行的,所以调用next的时候,生成器不会从函数开始执行,只是接着上一步停止的地方开始,然后遇到yield,就return出要生成的数,此步迭代结束。

下面认识一下生成器的send函数。

def foo():
    print("starting...")
    while True:
        res = yield 4
        print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(next(g))
starting...
4
********************
res: None
4
def foo():
    print("starting...")
    while True:
        res = yield 4
        print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(g.send(7))
starting...
4
********************
res: 7
4

send函数作用是发送一个参数给res,在每步return的时候,并没有把4赋值给res,下次执行的时候只好继续执行赋值操作,只好赋值为None,但是使用send的话,开始执行的时候,会先接着上一次(return 4)执行,先把7赋值给res,然后执行next的作用。

生成器的用处是什么,想象下在List很大的时候,会很占内存空间,比如获取0,1,2…,1000。

for n in range(1000):
    a=n

使用for的方法很占空间,可以用yield进行改写。

def foo(num):
    while num<10:
        num=num+1
        yield num
for n in foo(0):
    print(n)
1
2
3
4
5
6
7
8
9
10

但是在正常使用的时候,还是推荐使用range(python2中是xrange),它已经不是简单List了,是一个<class ‘range’>也就是生成器对象,python已经自己优化好了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值