2015-09-18 13 views
10

OK, więc ten fragment kodu pochodzi z pytania dotyczącego praktyki w mojej szkole. Mamy mentalnie przeanalizować kod i sprawdzić odpowiedź.Python Function Return Loop

Kiedy go najpierw przeanalizowałem, uzyskałem 4. Skopiowałem kod i przetransportowałem go przez IDLE i otrzymałem 8. Uruchomiłem debugger i zobaczyłem, że jeszcze: return zapętla instrukcję if else do x == 0, a następnie zwraca 1.

nie rozumiem, w jaki sposób powrócić 1 zbliża się do 8.

def foo(x=5): 
    if x == 0: 
     return 1 
    else: 
     return 2*foo(x-1) 

print(foo(3)) 

rozumiem, że dzwoni foo(x-1) wewnątrz funkcji foo(x=5) co czyni go sprawdzić, czy jeszcze raz i jeszcze raz, aż x == 0 następnie go zwraca 1. W jaki sposób powrót 1 kończy się drukowanie 8?

+6

Duplikat strony http://stackoverflow.com/questions/32653496/python-function-return-loop? – wap26

+0

'foo' to rekursywne obliczenie" 2 do _x_ mocy "dla nieujemnych wartości całkowitych _x_. (Jeśli pomnożył 'foo (x-1)' przez 'x' zamiast przez' 2', obliczałoby to "_x_ silnię".) –

+1

@ W3226 podany link wydaje mi się moim pytaniem – proxenmity

Odpowiedz

18

Będziesz się następujące połączenia do foo:

foo(3) -> foo(2) -> foo(1) -> foo(0) 

tych powróci

foo(0) -> 1 
foo(1) -> 2 * foo(0) -> 2 * 1 -> 2 
foo(2) -> 2 * foo(1) -> 2 * 2 -> 4 
foo(3) -> 2 * foo(2) -> 2 * 4 -> 8 

Czy teraz jasne?

+0

@JamesHaskett: ta odpowiedź (niejawnie) pokazuje metodę realizacji tej samej funkcji bez użycia rekursji. Dobrym ćwiczeniem byłoby zaimplementowanie 'foo' zarówno z rekurencją i bez niej, jak i porównania obu podejść. –

11

Myślę, że masz dobry pomysł (inaczej nie uzyskałbyś odpowiedzi 4), po prostu przerywasz zbyt wcześnie swoje ćwiczenia umysłowe.

Możesz śledzić zmiennych poprzez ich tabulacja podczas przechodzenia przez kod:

  • foo(3)
    • połączeń foo(3 - 1)foo(2)
      • rozmowy foo(2 - 1)foo(1)
        • wzywa foo(1 - 1)foo(0)
          • powraca 1
        • zostaje przywrócone 2 * foo(1 - 1)2
      • powraca 2 * foo(2 - 1)4
    • powraca 2 * foo(3 - 1)8
4

Rekursja działa odwrotnie niż pierwotnie oczekiwano. Nie zaczyna się od x = 3, ale zamiast tego wykonuje wszystkie rekursywne wywołania, a pierwsza wartość x wynosi 0.

Oto zmodyfikowana wersja twojego skryptu ilustrująca kolejność wykonywania kroków i jak dotarł do 8.

def foo(x=5): 
    if x == 0: 
     r = 1 
     print (x, r) 
     return r 
    else: 
     r = 2*foo(x-1) 
     print (x, r) 
     return r 

print(foo(3)) 

Zauważ, że pierwsza wartość x, która została wydrukowana, wynosi 1 zamiast 3, które dałeś. Gdy to zrozumiesz, zrozumiesz rekursję.