Return-wert einer Rekursiv-Funktion, Anfängerfrage

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
newbee
User
Beiträge: 7
Registriert: Sonntag 7. November 2010, 12:32

Hallo,
ich habe eine Anfängerfrage:

Code: Alles auswählen

def rechnen(korn, feld, gesamt):
    korn *=2
    gesamt +=korn
    feld +=1
    if feld < 5:
        return rechnen(korn, feld, gesamt)
    else :
        print gesamt
        return gesamt
    
print rechnen(1, 1, 1)
1. wenn die Funktion so aussieht wie jetzt, ist die Welt in Ordnung
2. wenn ich aber es so schreibe: if feld <5:
rechnen (korn, feld, gesamt)
also auf "return" verzichte, dann im "else-Zweig" zeigt die Funktion zwar (print-Anweisung) den "gesamt"-Wert, aber zum Schluss im Aufruf vom Hauptprogramm erscheint nur "None" als ob der "gesamt"-Wert nicht definiert wäre.
Hmm, warum? (im Vorschau fehlt die richtige Formatierung..)
Vielen Dank für Eure Hilfe
Zuletzt geändert von Anonymous am Sonntag 7. November 2010, 12:51, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@newbee: Das ``return`` gibt dann den `gesamt`-Wert an den vorletzten Aufruf zurück, aber *der* gibt dann `None` zurück, weil jede Funktion, wenn sie das Ende erreicht ohne auf ein ``return`` gestossen zu sein, den Wert `None` zurückgibt. Stell Dir einfach vor ganz am Ende steht immer ein ``return None``.
newbee
User
Beiträge: 7
Registriert: Sonntag 7. November 2010, 12:32

vielen Dank für die schnelle Antwort.
Hmm, ich stehe immer noch auf dem Schlauch...

Die Schleife wird durch "feld" gesteuert, sagen wir mal wir sind bei 4:
"korn" und "gesamt" werden richtig berechnet und in den jeweiligen Variablen gespeichert, "feld" bekommt "5"
, wir kommen zum "else"-Zweig und der (die Funktion endet) hat doch den return-Wert (also "gesamt")?
Die Funktion wird doch nicht ohne "return"-Anweisung (also im undefinierten Zustand) beendet ?
BlackJack

@newbee: Aber `gesamt` vom letzten Aufruf wird an die Stelle zurückgegeben wo es zuvor aufgerufen wurde, und das ist der ``if``-Zweig vom vorletzten Aufruf. Und da wird nichts mit dem Wert gemacht. Die Funktion läuft bis zum Ende durch und gibt dann `None` an den vorvorletzten Aufruf zurück. Und da passiert genau das gleiche.

Um eine rekursive Funktion zu verstehen, solltest Du vielleicht erst einmal eine "richtig" rekursive nehmen und keine die schon endrekursiv ist. Deine Funktion kann man auch ohne `gesamt` etwas einfacher schreiben:

Code: Alles auswählen

def rechnen(felder, korn=1):
    return korn + rechnen(felder - 1, korn * 2) if felder else 0
Selbst Deine endrekurive Variante hätte ich ein wenig kürzer geschrieben, ohne den lokalen Namen innerhalb eines Aufrufs etwas neues zuzuweisen. Das ist potentiell nur verwirrend weil man dann mehr Werte zu verschiedenen Zeitpunkten im Auge behalten muss:

Code: Alles auswählen

def rechnen(felder, korn=1, gesamt=0):
    if felder:
        return rechnen(felder - 1, korn * 2, gesamt + korn)
    else:
        return gesamt
Ich habe ausserdem die feste 5 aus der Funktion heraus genommen und `felder` runter- statt hochgezählt. Aufruf beider Funktionen mit ``rechnen(5)``.
newbee
User
Beiträge: 7
Registriert: Sonntag 7. November 2010, 12:32

Hallo,
vielen Dank für die ausführliche Antwort - erst jetzt habe ich den Ablauf richtig verstanden!

MfG
Antworten