2017-07-30 9 views
2

これは、定義された2つの発電機を使用してコードの私の作品です:私は実行するとジェネレータは複数回使用できますか?

one_line_gen = (x for x in range(3)) 

def three_line_gen(): 
    yield 0 
    yield 1 
    yield 2 

for x in one_line_gen: 
    print x 

for x in one_line_gen: 
    print x 

期待通りの結果がある:

0 
1 
2 

しかし、私は実行している場合:

for x in three_line_gen(): 
    print x 

for x in three_line_gen(): 
    print x 

結果は次のとおりです。

0 
1 
2 
0 
1 
2 

なぜですか?私はどの発電機も一度しか使用できないと思った。

+0

生成する発電機**機能**と混同しないでください。 –

+0

'def one_line_gen():return(x for range(3))' 'を使用した場合、最初の例は同等です(関数を呼び出すたびにジェネレータを生成します)。 –

+0

密接に関連しています:[ジェネレータの式対yield:なぜ 'next()'が動作しないのですか?(// stackoverflow.com/q/10958771) –

答えて

4

three_line_genは機能ではありません。それを呼び出したときに返すものは、ジェネレータであり、呼び出すたびにまったく新しいものです。あなたがこのようにカッコを入れるたびに:

three_line_gen() 

これは反復処理される新しいジェネレータです。あなたが最初

mygen = three_line_gen() 

を行うと、二回mygenを反復していたしかし、もしあなたが期待するように、二回目は失敗します。

0

ライナーが1つであるので、Generatorオブジェクトは3ライナーはfunctionです。 彼らは異なっていることを意味しました。

これら2つは似ています。

def three_line_gen_fun(): 
    yield 0 
    yield 1 
    yield 2 

three_line_gen = three_line_gen_fun() 
one_line_gen = (x for x in range(3)) 

type(three_line_gen) == type(one_line_gen) 
2

いいえ、ジェネレータを2回反復することはできません。その上を反復すると、ジェネレータは使い果たされます。あなたはしかしteeと発電機のコピーを作成することがあります。他の問題のため

from itertools import tee 

one_line_gen = (x for x in range(3)) 
gen1, gen2 = tee(one_line_gen) 
# or: 
# gen1, gen2 = tee(x for x in range(3)) 

for item in gen1: 
    print(item) 

for item in gen2: 
    print(item) 

Ofer Sadan's answerを参照してください。

0

はい、ジェネレータは一度しか使用できません。あなたは2台のジェネレータオブジェクトを持っています。

# Python 3 


def three_line_gen(): 
    yield 0 
    yield 1 
    yield 2 

iterator = three_line_gen() 
print(iterator) 
for x in iterator: 
    print(id(iterator), x) 

iterator2 = three_line_gen() 
print(iterator2) 
for x in iterator2: 
    print(id(iterator2), x) 

、結果は次のとおりです。

<generator object three_line_gen at 0x1020401b0> 
4328784304 0 
4328784304 1 
4328784304 2 
<generator object three_line_gen at 0x1020401f8> 
4328784376 0 
4328784376 1 
4328784376 2 
0

なぜ?私はどの発電機も一度しか使用できないと思った。

three_line_genへのすべての呼び出し()は新しいジェネレータを作成するため。

それ以外の場合は、発電機が使い果たされるまで順方向にしか動かないことは間違いありません。

ジェネレータは複数回使用できますか?

はい、結果がジェネレータの外部にバッファされている可能性があります。 1つの簡単な方法は、itertools.tee()を使用することです:

>>> from itertools import tee 
>>> def three_line_gen(): 
     yield 0 
     yield 1 
     yield 2 

>>> t1, t2 = tee(three_line_gen()) 
>>> next(t1) 
0 
>>> next(t2) 
0 
>>> list(t1) 
[1, 2] 
>>> list(t2) 
[1, 2] 
関連する問題