这是一个愚蠢的例子,基于我想做的更复杂的事情:
from typing import Generator
def f() -> Generator[list[int], None, None]:
result = list()
result.append(1)
if len(result) == 2:
yield result
result = list()
result.append(2)
if len(result) == 2:
yield result
result = list()
result.append(3)
if len(result) == 2:
yield result
result = list()
result.append(4)
if len(result) == 2:
yield result
result = list()
print(list(f()))
这里的重点是这个位被复制了多次:
if len(result) == 2:
yield result
result = list()
通常,我会把它改成这样:
from typing import Generator
def f() -> Generator[list[int], None, None]:
def add_one(value: int) -> None:
nonlocal result
result.append(value)
if len(result) == 2:
nonlocal_yield result
result = list()
result = list()
add_one(1)
add_one(2)
add_one(3)
add_one(4)
print(list(f()))
显然,
nonlocal_yield
不是一个东西。有没有一种优雅的方法来实现这一点?
我知道我可以创建完整的结果列表,即
[[1, 2], [3, 4]]
,然后返回它或 yield
单独的 2 元素子列表。像这样的东西:
from typing import Generator
def f() -> list[list[int]]:
def add_one(value: int) -> None:
nonlocal current
current.append(value)
if len(current) == 2:
result.append(current)
current = list()
result = list()
current = list()
add_one(1)
add_one(2)
add_one(3)
add_one(4)
return result
print(list(f()))
然而,这违背了发电机的目的。在没有更好的解决方案的情况下我会尝试它,但我很好奇是否有一种“纯粹的”生成器方法可以做到这一点。
一种可能性:
def f() -> Generator[list[int], None, None]:
def add_one(value: int) -> None:
nonlocal result
result.append(value)
if len(result) == 2:
yield result
result = list()
result = list()
yield from add_one(1)
yield from add_one(2)
yield from add_one(3)
yield from add_one(4)