2013-04-10 3 views
7

警告:極端な初心者の質問Pythonの関数は、返った後にその値をどのように覚えていますか?

私はレシピとして機能を考えていたようです。私の世界では、プログラムはレシピボックスであり、いくつかのレシピ(機能)は他のレシピ(他の機能)を必要とします。プロセッサは、命令をRAMに書き込んで処理してマスタレシピの実行を開始します。朝食クレープのように。ジュリアチャイルズから朝食クレープレシピを呼んでいます。あなたはクレープバターを一度作ってやる必要があります。それからあなたはまだクリープバッターを持っている間、あなたは繰り返しクリープを作ります。同時に、あなたが作ることができる様々な果物の準備があります。

私は明らかに分かりません。私はpythontutor.comを通してProject Euler Problem 2(フィボナッチ数も400万未満の合計)にpython wikiソリューションを実行しました。そして私は何かが私に起こったと思う。レシピを作成するたびに、同じプロセッサを使用するだけではなく、その機能を操作するためにいくつかのポットを備えたグノームが得られます。ポットは変数で、gnomeはレシピを作成し、コール関数が戻り値を期待していた場合、gnomeはそれらのポットの内容を呼び出し側に示します。呼び出し元は、次に戻っていくつかのものを見つけ、呼び出し元に戻り値を表示することができます。

したがって、AlがBobにクレープを作るように電話するとします。ボブはバッターを作りチャーリーに電話をかけて料理する。チャーリーはクレープを調理し、そのクレープをボブに提供し、ボブはそれをアルに与え、チャーリーに戻ります。誰がまだ存在するのですか?アルはボブがキッチンにチャーリーを隠していることを知らないが、チャーリーが最初のクレープを作った後でさえ、彼はまだキッチンにいて、クレープを作る方法を知っていて、彼がどれだけ多くのクレープバッターを残しているかを知っている。彼はすでに最初のクレープを返しましたが。

誰かが私のためにこれをクリアするのに役立つことができますか?

は、ここではPythonのwiki

def fib(): 
    x,y = 0,1 
    while True: 
     yield x 
     x,y = y, x+y 

def even(seq): 
    for number in seq: 
     if not number % 2: 
      yield number 

def under_a_million(seq): 
    for number in seq: 
     if number > 1000000: 
      break 
     yield number 

print sum(even(under_a_million(fib()))) 

からのコードだと、ここhttp://pythontutor.com/visualize.html

+6

あなたの混乱は理解できます。プログラムは、 'yield'キーワードを除いて、あなたが思うように(並べ替えて)動作します。あなたが説明するように、「収穫」はシンクの下にグノームを格納します。あなたが学んでいる間に、あなたは '収率'を避けることを選ぶかもしれません、またはあなたはそれを特に読むことを選択するかもしれません。 –

+1

ここに*ジェネレータ*があります。ジェネレータは 'yield'キーワードを見つけるたびに氷の上に置かれ、何かをループしているところに制御を戻します。 –

+0

http://www.jeffknupp.com/blog/2013/02/14/drastically-improve-your-python-understanding-pythons-execution-model/ – Torxed

答えて

2
それら 機能が機能していないので、これは

が、generatorsです。 yieldステートメントは値を返しますが、関数からは戻りません。ジェネレーターでnextを呼び出すたびに、最後の呼び出しからジェネレーターの実行を継続し、yieldステートメントに再び到達します。

1

原則として、最初の仮定は正しかった:関数の変数は、関数が実行されている間だけ利用可能である。ただし、あなたの場合はyieldステートメントを使用しています。その結果、関数呼び出しはイテレータを返します。イテレータは、呼び出されると次のyield文の値を返します。

イテレータの動作と詳細については、this postを参照してください。

2

値のシーケンスを生成する関数がある場合は、yieldを使用してgeneratorに変換することができます。

def func(): 
    for i in range(3): 
     yield i 

list(func()) ==> [0,1,2] 

for el in func(): 
    print(el) # 0 
       # 1 
       # 2 

毎回、歩留まりを呼び出すときは、関数がどこかで固定されます。それが再び呼び出されるとき、それは彼の最後の状態から続き、(要素を消費し終わらない限り)新たに開始しません。

この関数を呼び出すと、generatorが返されます。これは何かを反復処理することができます。

無限のメモリを使用せずに、無限のシーケンスを繰り返し処理できることに注意してください。

def inf(): 
    x = -1 
    while True: 
     x = x + 1 
     yield x 

for i in inf(): 
    if i < 10: 
     print(i) 
    else: 
     break 
関連する問題