2016-05-23 9 views
1

私は2つの発電機を得るために、私はフィルタリングすることができ、私はその後イテレータ内のデータを他の2つに迂回する方法はありますか?

x1, x2 = itertools.tee(x)

を使用して、イテレータをコピーすることができることを知っている:しかし、その後、私は同じことを実行します

filter(..., x1); filter(..., x2)

を計算は2回、すなわちx1とx2のxを通る。

したがって、私はそのような、より効率的なものだろう:

x1, x2 = divert(into x1 if ... else x2, x)

をこのようなものは、Python 3に存在していますか?

+0

何かばかげたことを言う危険があります - あなたは発電機にとどまって欲しいですか?普通の 'for'-loopで2つのリストを作成するだけです。しかし、あなたは 'x'を不必要に展開したくないと思いますか? – dwanderson

+0

質問が明確であればダンプはありません:-)はい、可能な限り私のメモリを解放するためにジェネレータのアプローチを維持したいと思います。 – Xiphias

答えて

0

私が知っているpythonで書かれた組み込みツールはありません。あなたが作ることができる各イテレーターの呼び出し順序が保証されていないので、作業をするのはちょっとおもしろいことです。たとえばxについては

x2値が続くx1値を作り出すことができるが、それは、信号値を生成するまで、あなたのコードはx1を反復処理することができ、それが信号値を生成するまでx2に反復...だから基本的にコードが希望x1の値が生成されるまですべてのx2の値を保持する必要があります。これは任意に遅れる可能性があります。

これが本当にやりたいことなら、ここでこのバッファの実行方法を簡単に考えてください。警告、それはまったくテストされておらず、xは無限のジェネレータだとします。さらに、この汎用イテレータを参照する__next__を実装する2つの実際のイテレータ・クラスをコーディングする必要があります.1つはcategory==True、もう1つはcategory==Falseです。エルス

class SeparatedIterator: 
    def __init__(self, iterator, filter): 
     self.it = iterator 
     self.f = filter 
     #The buffer contains pairs of (value,filterIsTrue) 
     self.valueBuffer = [] 

    def generate(): 
     value = next(self.it) 
     filtered = self.f(value) 
     self.valueBuffer.append((value, filtered)) 

    def nextValue(category): 
     #search in stored values 
     for i in range(len(self.valueBuffer)): 
      value, filtered = self.valueBuffer[i] 
      if filtered == category: 
       del self.valueBuffer[i] 
       return value 

     #else, if none of the category found, 
     #generate until one of the category is made 
     self.generate() 
     while self.valueBuffer[-1][1] != category: 
      self.generate() 

     #pop the value and return it 
     value, _ = self.valueBuffer.pop() 
     return value 

あなたはイテレータの呼び出し順序についての詳細な制御を持っている場合、あなたはイテレータ値を切り替えることよりカスタマイズや最適化された方法を実装するために、その知識を使用する必要があります。

+0

アイデアをお寄せいただきありがとうございます - 私はそれを似ていますが異なる方法で行うかもしれません。とにかく、あまり珍しいことではない、あらかじめ作成された解決策がないことに私は驚いています。 – Xiphias

+0

問題は一般的ではありませんが、まれではありません。問題は明らかな解決策がないことです。私の上記のソリューションは、値を格納するリストを使用し、恐ろしいパフォーマンスを持つことができます。新しい値リクエストごとにフル・バッファを繰り返すので、時間パフォーマンスがひどくなる可能性があります。カテゴリごとに2つのキューを使用すると、その問題は緩和されますが、カテゴリが見つかるまでの問題は発生しません。 –

関連する問題