2016-05-30 2 views
0

イテレータを特定の値で停止し、その値まで状態を保存し、保存された状態と元の状態の両方を返す次のコードがあります。私は与えられたbreak_pointまでの値を取得するためにitertoolsからtakewhile使用していますが、その後、私はそれらをマージするbreak_pointと初期イテレータまで保存されたイテレータにチェーンを使用します。最後に、itertools内のtakewhileが1つの値をとりすぎる

from itertools import takewhile, chain 

def iter_break(iterator_input, break_point): 

    new_iter = list(takewhile(lambda x: x <= break_point-1, iterator_input)) 
    return chain(iter(new_iter), iterator_input) 

import unittest 


class TestEqual(unittest.TestCase): 

    def test_iters(self): 

     it = iter(range(20)) 
     old_it = iter_break(it, 10) 
     self.assertEqual(list(it), list(old_it)) 

if __name__ == '__main__': 
    unittest.main() 

問題があります返されたイテレータと返されている完全なイテレータは、返されたものが1つの値を逃し、ブレークポイント自体に等しい値を見逃しているため、似ていません。助けてください。それはtakewhileでそれらの上に反復して

+0

break_point-1から "-1"を削除しようとするか、 "<="の代わりに "<"を実行してください –

+1

'takewhile'がiteratingを停止しても、条件に合う?もちろん、ブレークポイントはイテレータから消費されました。つまり、 'takewhile'が停止しました! –

答えて

3

itはちょうどそれがiterとないリストを作成しただけでイテレータだから、それはそれの前にすべての値を欠けて、ブレークポイントの値が欠落していないので、iter_sampleは値を使用しています。これは、条件がもはや満たされていないことを知るために、takewhileがその値を参照する必要があるため、ブレークポイント自体を含みます。

+0

ありがとう、isliceはトリックを行うようです。 –

+0

@ivan_bilan 'islice'は、値に関係なく固定数の要素を取りますが、あなたの質問は、イテレータが特定の値に達する前に停止する必要があることを示しています。 'range'を使ったテストは、すべての要素がその値に等しいインデックスを持っているので問題はありませんが、これはあなたが望むものではないようです。より複雑なリストを使ってテストしてみてください。また、問題はブレークポイントの損失ではなく、消費可能なイテレーターを渡していたという事実でした。あなたはそれを修正しましたか? –

+0

特定のインデックスで停止する必要があるので、isliceは何をすべきかを行います。また、値を消費しますが、チェーンを使用してスライスされたイテレーターと入力イテレーターに残っている残りの値をマージすると動作するようです。 –

関連する問題