"yield from" 在递归函数中是如何工作的?
How does "yield from" work in recursive functions?
我正在编写一些 python 代码,我需要在递归函数中使用生成器。这是我编写的一些代码来模仿我正在尝试做的事情。这是尝试 1.
def f():
def f2(i):
if i > 0:
yield i
f2(i - 1)
yield f2(10)
for x in f():
for y in x:
print(y)
这只打印 10,使用我在网上找到的 yield from
构造尝试 2。
def f():
def f2(i):
if i > 0:
yield i
yield from f2(i - 1)
yield from f2(10)
for x in f():
print(x)
这是我想要的,但我不明白发生了什么,yield from
在幕后做了什么,为什么我的第一次尝试不起作用?
您可以将 yield from
视为产生每个项目的 for 循环:
for i in f(10):
yield i
与yield from f(10)
相同。换句话说,它 产生 项目 来自 给定的可迭代对象,在这种情况下是另一个生成器。
yield from g()
将在新生成器 g
中递归,从该生成器
的每个 yield
语句中产生
所以
def g1():
yield from g2()
def g2()
for i in range(10):
yield i * 2
你可以认为 g1 中的 yield from
正在其内部展开 g2
,扩展成这样的东西
def g1():
for i in range(10):
yield i * 2
这不是正在发生的事情,因为你有作用域等,但是在 g1
中执行 yield from g2()
期间,解释器在 g2
中递归产生它产生的每个值,可能递归到另一个生成器。
现在考虑这个生成器
def flatten(maybe_it):
try:
for i0 in maybe_it:
for i1 in flatten(i0):
yield i1
except TypeError:
yield maybe_it
和yield from
可以改写为
def flatten(maybe_it):
try:
for i0 in maybe_it:
yield from flatten(i0):
except TypeError:
yield maybe_it
我正在编写一些 python 代码,我需要在递归函数中使用生成器。这是我编写的一些代码来模仿我正在尝试做的事情。这是尝试 1.
def f():
def f2(i):
if i > 0:
yield i
f2(i - 1)
yield f2(10)
for x in f():
for y in x:
print(y)
这只打印 10,使用我在网上找到的 yield from
构造尝试 2。
def f():
def f2(i):
if i > 0:
yield i
yield from f2(i - 1)
yield from f2(10)
for x in f():
print(x)
这是我想要的,但我不明白发生了什么,yield from
在幕后做了什么,为什么我的第一次尝试不起作用?
您可以将 yield from
视为产生每个项目的 for 循环:
for i in f(10):
yield i
与yield from f(10)
相同。换句话说,它 产生 项目 来自 给定的可迭代对象,在这种情况下是另一个生成器。
yield from g()
将在新生成器 g
中递归,从该生成器
yield
语句中产生
所以
def g1():
yield from g2()
def g2()
for i in range(10):
yield i * 2
你可以认为 g1 中的 yield from
正在其内部展开 g2
,扩展成这样的东西
def g1():
for i in range(10):
yield i * 2
这不是正在发生的事情,因为你有作用域等,但是在 g1
中执行 yield from g2()
期间,解释器在 g2
中递归产生它产生的每个值,可能递归到另一个生成器。
现在考虑这个生成器
def flatten(maybe_it):
try:
for i0 in maybe_it:
for i1 in flatten(i0):
yield i1
except TypeError:
yield maybe_it
和yield from
可以改写为
def flatten(maybe_it):
try:
for i0 in maybe_it:
yield from flatten(i0):
except TypeError:
yield maybe_it