yield from的具体用法

Python3.3新增的yield from表达式句法可把一个生成器的工作委托给一个子生成器。

在引入yield from之前,如果一个生成器根据另一个生成器生成的值产生值,则需要使用for循环。

def sub_yield():
    yield 1.1
    yield 1.2
    yield 1.3

def main_yield():
    yield 1
    for s in sub_yield():
        yield s
    yield 2
    yield 3

for i in main_yield():
    print(i)
# 输出
# 1
# 1.1
# 1.2
# 1.3
# 2
# 3

使用yield from也能达到这样的效果,并且代码看起来更优雅!

def sub_yield():
    yield 1.1
    yield 1.2
    yield 1.3

def main_yield():
    yield 1
    yield from sub_yield()
    yield 2
    yield 3

for i in main_yield():
    print(i)

上面代码for循环是客户代码,main_yield是委托生成器,sub_yield是子生成器。yield from暂停main_yield,sub_yield接手,直到它耗尽。sub_yield产生的值会绕过main_yield,直接传给客户代码的for循环使用。在此期间,main_yield处于暂停状态,看不到绕过它的那些值,当sub_yield耗尽后,main_yield恢复执行。

子生成器中有return语句时,返回一个值,在委托生成器中,通过含有yield from的表达式可以捕获那个值。

def sub_yield():
    yield 1.1
    yield 1.2
    yield 1.3
    return 'Done'

def main_yield():
    yield 1
    result = yield from sub_yield()
    print(f"{result}----->")
    yield 2
    yield 3

for i in main_yield():
    print(i)
# 输出
# 1
# 1.1
# 1.2
# 1.3
# Done----->
# 2
# 3

了解yield from的基本作用后,可以使用下面示例说明它的实际用途。

重新实现Chain

itertools里面有个chain生成器。它的作用用于从多个可迭代对象中产出项,先迭代第一个可迭代对象,然后迭代第二个,直到最后一个可迭代对象。

import itertools
c = itertools.chain([1, 2, 3], 'abc', (4, 5))
print(list(c))  # [1, 2, 3, 'a', 'b', 'c', 4, 5]

yield版本

def chain(*iterables):
    for it in iterables:
        for i in it:
            yield i

s = 'abc'
l = [1, 2, 3]
t = (4, 5)
print(list(chain(s, l, t)))

yield from版本

def chain(*iterables):
    for it in iterables:
        yield from it

s = 'abc'
l = [1, 2, 3]
t = (4, 5)
print(list(chain(s, l, t)))

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值