18

重複の可能性:
Pythonのyieldキーワードの説明

誰かがここのコードのこのビットでyieldステートメントが実際に何をするかを私に説明できますか?

 def fibonacci():
     a, b = 0, 1
     while True:
         yield a
         a, b = b, a+b

の数fibonacci():#ジェネレータをイテレータとして使用します。印刷番号

私がこれまでに理解していることは、finonacci()パラメーターなしで関数を定義しているということです。定義aしている関数の内部で、 b0と1に等しくなります。次に、これが当てはまる間、を生成しaます。これは実際に何をしているのですか?さらに、降伏しながらaaはに等しくなりbbはに等しくなりa + bます。

次の質問、の数について、fibonacci()これは関数のすべての数を意味しますか、それとも何を意味しますか?私は、yieldと'fornumber'が実際に何をしているのかについても同様に困惑しています。明らかに、私はそれがfibonacci()印刷番号のすべての番号を意味することを知っています。私は実際にそれを知らずに数を定義していますか?

ありがとう、はっきりしない場合は申し訳ありません。ところで、それはプロジェクトオイラーのためのものです。うまくプログラムする方法を知っていれば、これは簡単ですが、私はその場でこれを学ぼうとしています。

4

4 に答える 4

11

を使用yieldすると、関数がジェネレーターになります。ジェネレーターはa各ループで変数を生成し続け、ジェネレーターのnext()メソッドが呼び出されて次のループの反復に進むまで待機します。

または、あなたreturnまたはStopIterationが育てられるまで。

の使用法を示すためにわずかに変更されましたStopIteration

>>> def fib():
...     a = 0
...     b = 1
...     while True:
...         yield a
...         a = b
...         b += a
...         if a > 100:
...             raise StopIteration
...
>>>
>>> for value in fib():
...     print value
...
0
1
2
4
8
16
32
64
>>>

>>> # assign the resulting object to 'generator'
>>> generator = fib()
>>> generator.next()
0
>>> generator.next()
1
>>> for value in generator:
...     print value
...
2
4
8
16
32
64
>>>
于 2012-08-22T08:11:25.190 に答える
4

コードが呼び出さfibonacciれると、特別なジェネレータオブジェクトが作成されます。コードは実行されず、ジェネレータオブジェクトのみが返されることに注意してください。後でそのメソッドを呼び出すとき、関数はステートメントnextに遭遇するまで実行されます。yieldに提供されたオブジェクトyieldが返されます。メソッドを再度呼び出すとnext、関数は。に遭遇するまで再度実行されyieldます。これ以上ステートメントがなくyield、関数の終わりに達すると、StopIteration例外が発生します。

関数内のオブジェクトは、の呼び出し間で保持されることに注意してくださいnext。つまり、コードが次のループで実行を継続すると、呼び出されたスコープ内にあったすべてのオブジェクトは、前の呼び出しが返さyieldれた時点からの値を持ちます。next

ジェネレーターの優れた点は、forループを使用した便利な反復が可能になることです。forループは、fibonacci呼び出しの結果からジェネレーターを取得し、例外がnext発生するまでジェネレーターオブジェクトのメソッドを使用して要素を取得するループを実行します。StopIteration

于 2012-08-22T08:11:13.520 に答える
4

ジェネレーターには、その値のためにメモリーを消費しない iterable であるという特別な特性があります。

これは、反復中に必要になったときに新しい値を計算することによって行われます。

すなわち

def f():
    a = 2
    yield a
    a += 1

for ele in f():
    print ele

印刷します

 2

したがって、値を返し続けるイテラブルとして関数を使用しています。これは、メモリを大量に使用する必要があり、リスト内包表記を使用する余裕がない場合に特に便利です。

すなわち

li = [ele*10 for ele in range(10)]

リストとして int 用に 10 個のメモリ空間を使用します

ただし、単純に反復したい場合は、個別にアクセスしないでください

代わりに使用すると、メモリ効率が非常に高くなります

def f():
    i=0
    while i<10
        yield i*10
        i += 1

iが再利用され続けるため、1つのメモリスペースを使用します

これのショートカットは

ge = (i*10 for i in range(10))

次のいずれかを行うことができます

for ele in f():

for ele in li:

for ele in ge:

同等の結果を得るために

于 2012-08-22T08:20:33.817 に答える
1

この回答は、yieldステートメント、およびイテレータとジェネレータの優れた説明です。

具体的には、 の最初の呼び出しは0 にfibonaci()初期化され、 1 に初期化され、while ループに入り、 が返されます。次の呼び出しは、ステートメントの後に開始され、 to 、toに影響を与え、ステートメントの次の繰り返しに進み、ステートメントに再び到達し、再び戻ります。abayieldbaa+bbwhileyielda

于 2012-08-22T08:17:38.910 に答える