如何让生成器提前准备好下一个值?
How can I make a generator prepare the next value in advance?
我有一个生成器,它循环遍历大量元素并生成满足特定条件的元素。处理单个元素可能需要一段时间。一旦我 yield 该元素,在我的 main 函数中再次需要一段时间来处理它。
这意味着当我循环遍历生成器时,我必须等待生成器找到一个满足所有条件的元素,然后让我的主函数处理它,然后冲洗并重复。我想通过在需要时立即提供下一个值来加快速度。
def generate(a, b):
for stack in some_function(a, b):
# Check for multiple conditions. This
# takes a while.
# I'd like to run this code in the
# background while I process the
# previous element down below.
yield stack
for stack in generate(foo, bar):
# Process the stack. This can take
# a while too.
如何让生成器准备下一个值,以便在调用 next
时准备好?这可能开箱即用吗?我已经研究过协同程序和并发性,但它们似乎与我的问题无关。
这是我想出的解决方案:
from queue import Queue
from threading import Thread
def generate(a, b, queue):
for stack in some_function(a, b):
# Check for multiple conditions.
queue.put(stack)
queue = Queue()
thread = Thread(target=generate, args=(foo, bar, queue))
thread.start()
while thread.is_alive() or not queue.empty():
stack = queue.get()
# Process the stack.
如果堆栈的处理速度快于将它们添加到队列的速度,则 while 循环仍会运行,因为线程仍处于活动状态。如果线程死了,那么只要队列为空,循环就会运行。这显然是一种变通方法,因为 generate
不再是生成器 ,但它可以解决问题。
我有一个生成器,它循环遍历大量元素并生成满足特定条件的元素。处理单个元素可能需要一段时间。一旦我 yield 该元素,在我的 main 函数中再次需要一段时间来处理它。
这意味着当我循环遍历生成器时,我必须等待生成器找到一个满足所有条件的元素,然后让我的主函数处理它,然后冲洗并重复。我想通过在需要时立即提供下一个值来加快速度。
def generate(a, b):
for stack in some_function(a, b):
# Check for multiple conditions. This
# takes a while.
# I'd like to run this code in the
# background while I process the
# previous element down below.
yield stack
for stack in generate(foo, bar):
# Process the stack. This can take
# a while too.
如何让生成器准备下一个值,以便在调用 next
时准备好?这可能开箱即用吗?我已经研究过协同程序和并发性,但它们似乎与我的问题无关。
这是我想出的解决方案:
from queue import Queue
from threading import Thread
def generate(a, b, queue):
for stack in some_function(a, b):
# Check for multiple conditions.
queue.put(stack)
queue = Queue()
thread = Thread(target=generate, args=(foo, bar, queue))
thread.start()
while thread.is_alive() or not queue.empty():
stack = queue.get()
# Process the stack.
如果堆栈的处理速度快于将它们添加到队列的速度,则 while 循环仍会运行,因为线程仍处于活动状态。如果线程死了,那么只要队列为空,循环就会运行。这显然是一种变通方法,因为 generate
不再是生成器 ,但它可以解决问题。