2017-11-22 5 views
-1

私はPythonでジェネレータを経由していましたが、ジェネレータの利点を理解しました。Pythonジェネレータのforループ反復の効率

next(mygenerator) 
:上記の例では、代わりに、forループの

for i in mygenerator: 
    print i 

言って、私は

ケースBを使用した:

mygenerator = (x*x for x in range(3)) 

ケースAの例を考えてみ

ケースAとケースB複雑さの点で同じですか?

私は、ケースAのようにループをforループして使用している場合は、ジェネレータの利点を得ることができますか?または、私はいつもより良い利益のためにnext()を使用しなければなりませんか?

+0

'next()'は**一度に**一つのステップになります。 'for'と' while True'ループを比較する必要があります。最終的に同じ結果にアクセスするが、別々の 'next()'グローバルルックアップと呼び出しがあるため、速度が遅くなります。 –

答えて

4

まず、next()ではないです。 next()はイテレータで次の値を生成しますが、ループを使用するforのドロップイン置換ではありません。あなたはwhile Trueループを使用する必要があると思います

while True: 
    try: 
     i = next(mygenerator) 
    except StopIteration: 
     break 

これが繰り返さnext名前解決を必要とするので、これは、遅くです。そうでなければ効率的ではありません。

forは(selfが返される)発生器にiter()を使用し、次いで内部呼び出しなるnext()同じ方法、イテレータに__next__()メソッドを呼び出します。何かがより効率的に(パフォーマンス)であれば

最終的には、timeit moduleで、テストすることができます。

>>> from timeit import timeit 
>>> while_loop = '''\ 
... while True: 
...  try: 
...   i = next(g) 
...  except StopIteration: 
...   break 
... 
... ''' 
>>> timeit('for i in g: pass', 'g = (x*x for x in range(1000000))') 
0.15362663206178695 
>>> timeit(while_loop, 'g = (x*x for x in range(1000000))') 
0.568918940029107 

だから、100万個のアイテムを生産する発電機のため、forループは、ほぼ4倍高速です。

ジェネレータ関数とジェネレータ式の利点は、メモリ効率であり、多くの場合、コードの明瞭度です。 fornext()は、ジェネレータから値を取得するための2つの非常に異なるユースケースです。問題の解決に必要なものを使用してください。

+0

ええ、ええ!私はその事実を認識しています。私が確認しようとしていたのは、あなたが言っているように、while(True)とnext()を使用していて、質問に言及したケースAが内部実装で同じであった場合でしたか? – syam

+1

@syam: 'for'はオブジェクトに対して' iter() 'を使い、' next() 'と同等の道徳を呼び出します。しかし、これはCコードで発生するので、はるかに効率的です。 –

関連する問題