如何让生成器函数的初始化代码立即运行,而不是在第一次调用时?

18 投票
5 回答
6664 浏览
提问于 2025-04-16 16:04

我有一个生成器函数,大概是这样的:

def mygenerator():
    next_value = compute_first_value() # Costly operation
    while next_value != terminating_value:
        yield next_value
        next_value = compute_next_value()

我希望在调用这个函数的时候,初始化步骤(在while循环之前)就能立刻执行,而不是等到第一次使用生成器的时候才执行。有什么好的方法可以做到这一点吗?

我想这样做是因为这个生成器会在一个单独的线程(或者进程,或者其他多进程使用的东西)中运行,而我在短时间内不会使用返回的值,而且初始化的过程有点耗时,所以我希望它能在我准备使用这些值的时候就开始初始化。

5 个回答

9

你可以很简单地通过使用 itertools.chain 来创建一个“预先准备好的”迭代器:

from itertools import chain

def primed(iterable):
    """Preprimes an iterator so the first value is calculated immediately
       but not returned until the first iteration
    """
    itr = iter(iterable)
    try:
        first = next(itr)  # itr.next() in Python 2
    except StopIteration:
        return itr
    return chain([first], itr)

>>> def g():
...     for i in range(5):
...         print("Next called")
...         yield i
...
>>> x = primed(g())
Next called
>>> for i in x: print(i)
...
0
Next called
1
Next called
2
Next called
3
Next called
4
18

我需要一些类似的东西。最后我找到了这个方法。把生成器函数放到一个内部函数里,然后返回它的调用结果。

def mygenerator():
    next_value = compute_first_value()

    def generator():
        while next_value != terminating_value:
            yield next_value
            next_value = compute_next(next_value)

    return generator()
15

在编程中,有时候我们需要处理一些数据,比如从一个地方获取数据,然后把它放到另一个地方。这就像把水从一个杯子倒到另一个杯子一样。

有些时候,我们会遇到一些问题,比如数据格式不对,或者数据不完整。这就像你想把一杯牛奶倒到一个小杯子里,但小杯子太小,装不下所有的牛奶。

为了避免这些问题,我们可以提前检查数据,确保它们是正确的。这样就能顺利地把数据从一个地方转移到另一个地方,而不会出现溢出的情况。

总之,处理数据的时候,要注意数据的格式和完整性,这样才能让我们的程序顺利运行。

class mygenerator(object):
    def __init__(self):
        self.next_value = self.compute_first_value()
    def __iter__(self):
        return self
    def next(self):
        if self.next_value == self.terminating_value:
            raise StopIteration()
        return self.next_value

撰写回答