使用 next(generator) 时的意外输出

unexpected output when using next(generator)

代码如下:

from typing import Any, Generator, List, Set, Union
stream_type = Union[List[Any], str]

def valid_posts(stream: Generator[stream_type, None, None]) -> Set[int]:
    result = set()
    for post in stream():
        if post == "end_of_session":
            yield result
            result = set()       
            continue
        if post[2] == "hello":
            result.add(post[1])    
            

def stream():
    data = [
        [1, 1, "hello"],
        [1, 1, "world"],
        [1, 2, "hello"],
        [1, 2, "world"],
        [1, 3, "hello"],
        [1, 3, "world"],
        [1, 1, "hello"],
        [1, 1, "world"],
        "end_of_session",
        [2, 1, "hello"],
        [2, 1, "world"],
        [2, 2, "world"],
        [2, 2, "world"],
        [2, 3, "world"],
        [2, 3, "world"],
        "end_of_session",
    ]
    for item in data:
        yield item


# for post in valid_posts(stream):
#     print(post)
print(next(valid_posts(stream)))
print(next(valid_posts(stream)))
print(next(valid_posts(stream)))
print(next(valid_posts(stream)))

当我使用现在注释掉的两行 (for post in valid_posts(stream): print(post)) 时,它打印出预期结果:

{1, 2, 3}
{1}

但是当我使用 print(next(valid_posts(stream))) 的四行时,它令人惊讶地打印出这些:

{1, 2, 3}
{1, 2, 3}
{1, 2, 3}
{1, 2, 3}

我的理解是我们可以用next()调用生成器,它一个一个地产生结果直到最后,但是为什么在这种情况下它只是重复打印第一个结果?谢谢

当你做 for post in valid_posts(stream): 你实际上做了:

vp = valid_posts(stream) # save the iterator returned from valid_posts
print(next(vp))
print(next(vp))
print(next(vp))
print(next(vp))
# ... a until StopIteration is raised

在您的使用中,您一遍又一遍地调用 valid_posts,而不是使用同一个迭代器。

编辑:
请注意,您也有严重的类型错误。
类型注释只是提示,PyCharm 当我将你的代码粘贴进去时,我尖叫起来。
注释存在并且代码运行的事实并不意味着代码符合注释。