【问题标题】:Why does iter(v,w) return a class when the callable is a generator?当可调用对象是生成器时,为什么 iter(v,w) 返回一个类?
【发布时间】:2021-04-03 19:24:50
【问题描述】:

考虑以下最小工作示例:

import itertools

for i in iter(itertools.count, 10):
    print(i)

我预计输出计数为 10。但是,输出一次又一次是 count(0)。打印类型会给出<class 'itertools.count'>

iter(object, sentinel) 的文档说明如下:

在这种情况下创建的迭代器将调用 object,每次调用其__next__() 方法时不带任何参数;如果返回的值等于sentinelStopIteration 将被提升,否则该值将被返回。

这对我来说就像我所期望的行为。我忽略了什么?可选的额外问题:iter 如何使 object 成为生成器并获得预期的行为?

【问题讨论】:

    标签: python python-3.x iterator


    【解决方案1】:

    充实 2-arg iter 的文档,它的工作原理如下:

    def two_arg_iter(object, sentinel):
        while True:
            temp = object()
            if temp == sentinel:
                break
            yield temp
    

    在您给出的案例中,这正是您所看到的。注意:

    >>> itertools.count()
    count(0)
    

    count(0) 永远不会等于 10,所以你会一直得到count(0)

    不过,我不清楚你在问什么。我相信,这些中的任何一个都会做你真正想要的:

    for i in itertools.count(10):
    

    或者,冗余,

    for i in iter(itertools.count(10)):
    

    认识到 2-arg iter 是一种与 1-arg iter 截然不同的野兽,这可能会有所帮助。

    【讨论】:

    • 很好的解释。 TIL 2-arg 迭代器。不确定这是他想要的: - 在打印十之后中断? for i in count(0): print(i);如果 i == 10:中断;
    • @DanielHao 是的,“数到 10”对我来说听起来像是 iter(itertools.count().__next__, 10)
    • 哇!不知道我在圣诞节晚上碰到了一位专家……你是 Timsort 混合分拣设计师吗?....
    • 连同answer of a related question,似乎我将生成器函数生成器迭代器混淆了,而忽略了__next__()方法的确切位置叫做。感谢您的详细回答!至于原因:我想在不诉诸break 的情况下迭代生成器。使用two_arg_iter() 似乎更符合pythonic,因为在这种情况下的文档中甚至建议使用它。现在我必须通过 __next__() 方法(感谢 @KellyBundy),这似乎更像是一个 hacky 解决方法。
    • 在这种情况下,itertools.takewhile(lambda i: i != 10, itertools.count()) 的变体可能足以隐藏 hacky 部分 ;-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 2022-07-21
    相关资源
    最近更新 更多