Frage zur Rekursion

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.
_nohtyp_
User
Beiträge: 127
Registriert: Mittwoch 8. Januar 2014, 15:38

Danke!
Die Lösung:

Code: Alles auswählen

def lese_wort(sprung, eingabe):
    if sprung == 0:
        return False

    anzahl_zeichen = eingabe[sprung - 1]
    wort = eingabe[sprung:sprung + int(anzahl_zeichen)]

    sprung = eingabe[
        sprung + int(anzahl_zeichen):sprung + int(anzahl_zeichen) + 1]
    sprung = ''.join(sprung)
    return sprung, wort


eingabe = list('4Satz03Das') + ['17'] + list('3ein13ist') + ['12']
sprung = 7

satz = []

while lese_wort(int(sprung), eingabe) != False:
    sprung, wort = lese_wort(int(sprung), eingabe)
    satz.append(wort)

for satzteil in satz:
    print ''.join(satzteil),
Verbesserungsvorschläge erwünscht!
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@_nohtyp_: die natürlich Schleifenbedingung wäre wohl "while sprung>0:", denn »lese_wort« doppelt aufzurufen ist blöd (was Laufzeit, Verständlichkeit, Komplezität betrifft). »sprung« würde ich an einer anderen Stelle in ein int verwandeln, wie übrigens »anzahl_zeichen« auch. Was machen denn die Zeilen 8-10 konkret?
_nohtyp_
User
Beiträge: 127
Registriert: Mittwoch 8. Januar 2014, 15:38

In Zeile 8 bis 10 wird das Zeichen nach dem Wort gesucht und unter sprung gespeichert. Da sprung eine Liste ist, wird sprung in einen string gecastet.
BlackJack

@_nohtyp_: Sirius3 hat es im Grunde ja schon mit der Abbruchbedingung der ``while``-Schleife indirekt gesagt: Der Rückgabewert von Funktionen sollte möglichst immer den gleichen Typ haben. Eine Funktion die mal ein Tupel mit zwei Werten zurück gibt und mal einen Wahrheitswert zwingt den Aufrufer jedes mal zu prüfen was er da eigentlich zurück bekommen hat, bevor er mit dem Wert etwas anstellt. Manche APIs machen so etwas trotzdem, geben dann aber `None` zurück wenn sie ”Nichts” zurückgeben wollen und nicht `False`. Denn wenn eine Funktion `False` aber niemals `True` zurück geben kann, ist das eine komische Asymmetrie.

Falls für Sprung 0 übergeben wird, könnte man auch entweder so etwas wie ``(0, None)`` zurück geben, oder sogar noch besser eine Ausnahme auslösen, weil 0 an der Stelle ja im Grunde kein gültiger Index ist für eine Funktion die Indexe in die Zeichenkette mit 1 beginnend akzeptiert.

Der Test des Rückgabewertes mit ``function(something) != False`` ist auch unschön, weil im Grunde überflüssig, wie die meisten Vergleiche mit literalen Wahrheitswerten. Da sonst nur Tupel mit 2 Elementen zurück geliefert werden, die im boole'schen Kontext immer ”wahr” sind, hätte man das besser als ``while function(something):`` ausgedrückt. Was auch mit `None` anstatt `False` funktioniert hätte.

Zu den Zeilen 8 bis 10 hatte ich ja schon etwas geschrieben, warum das unnötig umständlich ist. Und eine Liste mit einem Element das eine Zeichenkette ist in eine Zeichenkette zu ”casten” geht deutlich einfacher in dem man einfach dieses eine Element aus der Liste holt, statt `join()` mit seiner internen Schleife zu bemühen.
Antworten