2016-12-08 3 views
0
def test(n): 
    if n == 0: 
     return 
    print("This should print n times") 
    test(n - 1) 

    print("This should not print") 


test(2) 

出力:この再帰関数でこの出力を取得するのはなぜですか?

This should print n times 
This should print n times 
This should not print 
This should not print 

なぜThis should not printは、関数は、それ自体(再帰)を呼び出したときに、プリントアウトしますでしょうか?一番上でもう一度やり直すのではないですか?

+1

初めてはい、が、その後、あなたは、再帰呼び出しから戻ると呼び出された関数が終了するまで再帰が唯一の更なる実行を中断しているので、あなたは最後の 'print' –

+1

に達します。 "This should should be print"をしたくない場合は、 'return test(n-1)'にしてください。 – MSeifert

+0

http://pythontutor.com/ – jonrsharpe

答えて

0

はい、部分的に正しいです。関数が呼び出されると、関数は上から終わりまで実行されるか、停止するように指示されます(たとえば、戻ります)。関数が実行された後は、関数を呼び出した行からプログラムが続行されます。例えば。

>>> def myFunc(): 
    print("This function is running") 


>>> def OtherFunc(): 
    myFunc() 
    print("The other function has finished running") 

>>> OtherFunc() 
This function is running 
The other function has finished running 

期待されたことは、関数呼び出しがreturnキーワードとして機能し、関数をただちに終了させることでした。 (nは実数で下塗りして)あなたのプログラムは、しかし、このように行動:

def test(2): 
    if 2 == 0: 
     return 
    print("This should print n times") 
    test(2 - 1) #The program is told to run the function again 

def test(1): 
     if 1 == 0: 
      return 
     print("This should print n times") 
     test(1 - 1) #The program is told to run the function again 

def test(0): 
      if 0 == 0: 
       return #This exits the function, and returns to the function that called it, test(1) 

print("This should not print") #This is the only line left in test(1), so it runs, and the returns to test(2), which called test(1) 

print("This should not print") #This is the only line left in test(2), so it is run. The program ends as there are no more lines of code after when you called test(2) 

だから、それが完了した関数呼び出しの後に実行される機能、の現在の実行を終了していない関数を呼び出します。

このコードは、あなたがやりたいことになります。

def test(n): 
    if n == 0: 
     return 
    print("This should print n times") 
    test(n - 1) 

    return #This will exit the function 

    print("This should not print") 


test(2) 

私はこれが助けを願って!

0

テスト(n-1)が内部リターンに達すると、不要な印刷が実行されます。戻り値は現在の関数呼び出しを終了し、呼び出された場所の次の行に続きます。それはスタック全体をクリアしません。

0

ほとんどがウェルレルです。あなたが上に乗っている部分は、あなたが「始めよう」と言うときです。関数が開始していない - それは自身を呼び出しています。これは、純粋な関数で見やすくなります - 追加を見てください。

def add(x, y): 
    if y == 0: 
     return x 
    return 1 + add(x, y-1) 

これは(これはひどいアイデアですが、例示的な目的のために...)さんは、いくつかの呼び出しを介してこれを追跡でき、それらをカウントすることにより、基本的に2つの番号を追加します。あなたの関数は、わずか開始した場合等において考えられるように答えは、100ではありませんが

>>> add(100, 4) = 1 + add(100, 3) 
    # because we're returning 1 + add(x, y-1) 
... add(100, 3) = 1 + add(100, 2) 
... add(100, 2) = 1 + add(100, 1) 
... add(100, 1) = 1 + add(100, 0) 
... add(100, 0) = 100 # this is called the base case. 

。バック機能の本来の実行に差し込むその値にadd解決への呼び出しのそれぞれ、あなたが持っているので:方法のうちの例では

>>> add(100, 4) = 1 + (1 + add(100, 2)) # subbing out...add(100, 3) 
       = 1 + (1 + (1 + add(100, 1))) # ... add(100, 2) 
       = 1 + (1 + (1 + (1 + add(100, 0)))) # ... add(100, 1) 
       = 1 + (1 + (1 + (1 + 100))) # ... add(100, 0) 
       = 1 + 1 + 1 + 1 + 100 # because addition is associative 
       = 104 

を、私たちはどのようにそれを見ることができますあなたの機能に適用されます。条件式のreturnは完全に機能しますが、最も内側の関数からのみ起動します。

# where a = "This should print n times" 
# and b = "This should not print" 
>>> test(2) = print(a); test(1); print(b) 
... test(1) = print(a); test(0); print(b) 
... test(0) = None # because of the early-exit 

ポップのすべてのそれらのもの、あなたが持っている:2 print(a) sおよび2 print(b)秒を持っている

>>> test(2) = print(a); (print(a); None; print(b)); print(b) 
#   test(1) ---^ 
#   test(0)---------------^ 

関連する問題