0Pricing
Python Academy · 课时

yield from 与委托

组合生成器

yield from 与委托 是 CoddyKit 上的免费 Python Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Python Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Python Academy 课程共包含 4 节课。

yield from 解决的问题

当一个生成器想要生成另一个可迭代对象中的所有值时,您可以编写一个手动循环。yield from 用一行代码就能完成同样的事情。

def manual():
    for x in [1, 2, 3]:
        yield x

print(list(manual()))

介绍 yield from

yield from iterable 会委托给该可迭代对象,依次生成其中的每个值。相比转发循环,这种写法更短、更清晰。

def delegate():
    yield from [1, 2, 3]

print(list(delegate()))

组合多个来源

您可以串联多个 yield from 语句,以惰性方式连接多个序列。

def chained():
    yield from 'ab'
    yield from [1, 2]
    yield from range(2)

print(list(chained()))

委托给另一个生成器

被委托的可迭代对象本身可以是生成器,这样您就能将多个生成器组合成更大的生成器。

def evens(n):
    for i in range(n):
        if i % 2 == 0:
            yield i

def report(n):
    print('evens:')
    yield from evens(n)

print(list(report(6)))

展平嵌套列表

yield from 的经典用途是递归展平:生成器在处理子列表时委托给自身。

def flatten(items):
    for item in items:
        if isinstance(item, list):
            yield from flatten(item)
        else:
            yield item

print(list(flatten([1, [2, [3, 4]], 5])))

yield from 与循环

下面两个版本会产生相同的输出。出于可读性考虑,通常更推荐 yield from,因为它还会转发发送值和返回结果等高级功能。

def with_loop(src):
    for x in src:
        yield x

def with_yield_from(src):
    yield from src

print(list(with_loop(range(3))))
print(list(with_yield_from(range(3))))

捕获子生成器的返回值

当被委托的生成器通过 return 返回一个值时,yield from 表达式的结果就是该值。这样,子生成器就可以报告结果。

def counter(n):
    count = 0
    for i in range(n):
        yield i
        count += 1
    return count

def driver():
    total = yield from counter(3)
    print('subgen yielded', total, 'items')

list(driver())

构建流水线

使用委托可以轻松地将流水线拆分为具有名称的阶段,并将它们组合起来。

def source():
    yield from range(5)

def only_odd(src):
    for x in src:
        if x % 2 == 1:
            yield x

def pipeline():
    yield from only_odd(source())

print(list(pipeline()))

委托给任意可迭代对象

yield from 不仅适用于生成器,也适用于任意可迭代对象:列表、元组、集合、字符串、字典键等。

def mixed():
    yield from {1, 2, 3}
    yield from ('a', 'b')

result = list(mixed())
print(sorted(str(x) for x in result))

按顺序合并生成器

您可以构建一个依次遍历多个来源的生成器,这对于连接数据流很有用。

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

print(list(concat([1, 2], [3], [4, 5])))

可读性更佳

对于深度嵌套或树状数据,yield from 可以让递归生成器保持简短,并清楚表达其意图。

def walk(tree):
    yield tree['name']
    for child in tree.get('children', []):
        yield from walk(child)

tree = {'name': 'root', 'children': [
    {'name': 'a'},
    {'name': 'b', 'children': [{'name': 'c'}]}
]}
print(list(walk(tree)))

快速检查

检验您对 yield from 的理解。

回顾

您学习了yield from 和委托:

  • 它会转发内部可迭代对象中的每个值。
  • 它可以组合生成器,并支持递归展平。
  • 它可以捕获子生成器的返回值。
  • 相比手动转发循环,它更加清晰。

下一门课程:使用线程和多进程实现并发。

常见问题解答

「yield from 与委托」课时是免费的吗?

是的 — 「yield from 与委托」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。

「yield from 与委托」这节课中我会学到什么?

组合生成器 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Python Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「yield from 与委托」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Python Academy 课中编写并运行代码吗?

能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 迭代器协议
  2. 生成器函数
  3. 生成器表达式
  4. yield from 与委托
← 返回 Python Academy