Python 生成器从嵌套非生成器函数产生

问题描述 投票:0回答:1

这是一个愚蠢的例子,基于我想做的更复杂的事情:

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()))

然而,这违背了发电机的目的。在没有更好的解决方案的情况下我会尝试它,但我很好奇是否有一种“纯粹的”生成器方法可以做到这一点。

python generator nested-function
1个回答
0
投票

一种可能性:

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)
© www.soinside.com 2019 - 2024. All rights reserved.