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 反馈 — 无需本地设置。