2016-07-17 3 views
3

私は、要素の大きなリストをループし、特定の条件を満たすものを生成するジェネレータを持っています。 1つの要素を処理するのに時間がかかることがあります。一度その要素を得ると、もう一度私の主な機能でそれを処理するのに時間がかかります。ジェネレータで次の値を事前に準備するにはどうすればよいですか?

これは、ジェネレータをループするときにジェネレータがすべての条件を満たす要素を見つけるのを待ってから、メイン関数がそれを処理してリンスして繰り返す必要があることを意味します。私はそれを必要とするとすぐに次の価値を利用できるようにすることによってスピードアップしたいと思います。

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が呼ばれたとき、それは準備ができているように、発電機は、次の値を準備するために得ることができますか?これは箱からでも可能ですか?私はすでにコルーチンと同時実行性について調べましたが、私の問題には関係していないようです。

+1

あなたが現在のものを得る前に次のものを見つけない限り、あなたはできません。その時は*どこかに取られなければならない*。 – jonrsharpe

+0

@jonrsharpeジェネレータを別のスレッドに入れてバックグラウンドで実行する方法はありませんか? – fenceop

+0

私は[このレシピ](http://code.activestate.com/recipes/578671-generator-with-lookahead/)に出会いました。同様の手法を使用できるかどうかを調べるには、GILを調べなければなりません。 – fenceop

答えて

1

これは私が思いついたのソリューションです:

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はもはや発電機ではないため、明らかに回避策ですが、それはトリックです。

関連する問題