【问题标题】:How to create a generator function that produces a specific number of values?如何创建生成特定数量值的生成器函数?
【发布时间】:2020-09-16 01:57:18
【问题描述】:

我正在尝试创建一个接受 1 个或 1+ 个参数的生成器函数。在其他可迭代对象不再产生值之后,它应该返回具有最多值的可迭代对象的剩余高值的可迭代对象。

例如:

 for i in func('dfg', 'dfghjk', [1,2]):
    print(i)

prints -> h
          j
          k

因为具有第二多值的参数“dfg”在 3 处停止生成值。 具有最多值的参数“dfghjk”然后产生“hjk”(剩余值)。

这里的问题是可迭代对象可能是有限的,也可能不是有限的,因此我无法计算参数的长度或将其添加到其他数据结构中。

任何帮助都会很棒,谢谢!

【问题讨论】:

    标签: python generator


    【解决方案1】:

    为了解决您的问题,我会尝试手动耗尽所有迭代器,直到只剩下一个。

    def foo(*iterables):
        iterators = [iter(x) for x in iterables]
        while len(iterators) > 1:
            for idx, it in enumerate(iterators[:]):
                try:
                    peek = next(it)
                except StopIteration:
                    # remove the iterator when exhausted
                    iterators.pop(idx)
    
        yield peek
        yield from iterators[0]
    

    请注意,要使其正常工作,您需要确保可迭代对象确实是迭代器(使用 iter 转换它们)。您还需要存储从迭代器获得的最后一个元素。请注意,因为我们只使用迭代器接口,所以无限迭代器工作得很好:

    >>> it = func([1], itertools.count(), [2,2])
    >>> for _ in range(3): print(next(it))
    2
    3
    4
    

    【讨论】:

    • 哦,我明白了。因此,当迭代器引发 StopIteration 时,我们将其从迭代器列表中弹出以耗尽列表。但是,yield from iterators[0] 有什么作用呢?
    • 哦,我明白了。 Yield 意味着您只想从迭代器列表中产生值,这将只是剩下的迭代器,因为所有其他迭代器都被弹出了。非常感谢!
    • 正确!如果您需要使用迭代器做相关的事情,我建议您查看 itertools 模块,对于大多数用例,您可以使用其中的一种解决方案。
    猜你喜欢
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多