Hallo zusammen,
ich möchte eine rekursive Funktion schreiben, die eine beliebige Liste komplett umkehrt. Leider fehlt mir dafür jeglicher Ansatz. Kann mir da jemand helfen? Bin noch Anfänger in Programmieren...
Vielen Dank, Andi
Umkehr einer Liste (rekursiv)
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Wozu? Sowas gibt es schon:
Und Rekursion macht überhaupt keinen Sinn in diesem Zusammenhang, es sei denn du hast eine verschachtelte Liste.
Aber ich gehe mal davon aus, das es eine Hausaufgabe ist?
Code: Alles auswählen
>>> l=[1,2,3]
>>> l.reverse()
>>> l
[3, 2, 1]
Aber ich gehe mal davon aus, das es eine Hausaufgabe ist?
Bottle: Micro Web Framework + Development Blog
-
- User
- Beiträge: 79
- Registriert: Montag 12. Oktober 2009, 11:50
Verstehe ich jetzt nicht, ist doch das was Defnull geschrieben hat, oder?Panke hat geschrieben:Eine umgekehrte Liste, ist das erste Element dieser Liste und davor die Umkehrung der Restliste.
Ich glaube das war die Erklärung für eine mögliche Rekursion. Verwenden will man so etwas natürlich nicht.Gabelmensch hat geschrieben:Verstehe ich jetzt nicht, ist doch das was Defnull geschrieben hat, oder?Panke hat geschrieben:Eine umgekehrte Liste, ist das erste Element dieser Liste und davor die Umkehrung der Restliste.
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Eher das letzte Element der Liste und danach die Restliste. Im Endeffekt das gleiche, macht aber mehr Sinn in der Implementierung.Panke hat geschrieben:Eine umgekehrte Liste, ist das erste Element dieser Liste und davor die Umkehrung der Restliste.
Bottle: Micro Web Framework + Development Blog
Hallo zusammen,
danke für euere schnellen Antworten! Ja, es geht tatsächlich um eine "Hausaufgabe", in der eben auch die Anwendung von Rekursionen geübt werden soll. Sonst hätte ich schon auch auf reverse() zurückgegriffen
Der Aufgabentext lautet lediglich: "Schreiben Sie eine rekursive Funktion zur kompletten Umkehr einer Liste!"
danke für euere schnellen Antworten! Ja, es geht tatsächlich um eine "Hausaufgabe", in der eben auch die Anwendung von Rekursionen geübt werden soll. Sonst hätte ich schon auch auf reverse() zurückgegriffen
Der Aufgabentext lautet lediglich: "Schreiben Sie eine rekursive Funktion zur kompletten Umkehr einer Liste!"
Dann such dir einen Weg aus und probier es!Defnull hat geschrieben:Eher das letzte Element der Liste und danach die Restliste. Im Endeffekt das gleiche, macht aber mehr Sinn in der Implementierung.Panke hat geschrieben:Eine umgekehrte Liste, ist das erste Element dieser Liste und davor die Umkehrung der Restliste.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Generelle Tipps für rekursive Programmierung:
Jeder Schritt muss dich näher ans Ziel bringen. Das heißt, das du in jeder Rekursionsstufe einen Teil des Problems lösen musst und nur den Rest rekursiv weiter reichen darfst. Tust du das nicht, wird das Problem nicht kleiner und die Rekursion läuft ewig.
Besonderes Augenmerk musst du auf die Terminierung richten, also den Fall, bei dem deine Funktion NICHT rekursiv sich selbst auf ruft, sondern ihr Teilproblem vollständig lösen kann. Ohne eine Terminierung würde die Funktion unendlich lange sich selbst aufrufen.
Du schreibst also eine Funktion, die einen Teil des Problems selbst löst und sich mit dem Resetproblem erneut (rekursiv) aufruft. Dann wird die eigene Lösung und der Rückgabewert des rekursiven Aufrufs kombiniert und zurück gegeben. Wenn es kein Resetproblem mehr gibt, sind wir fertig (terminiert) und geben nur das eigene Ergebnis zurück.
Jeder Schritt muss dich näher ans Ziel bringen. Das heißt, das du in jeder Rekursionsstufe einen Teil des Problems lösen musst und nur den Rest rekursiv weiter reichen darfst. Tust du das nicht, wird das Problem nicht kleiner und die Rekursion läuft ewig.
Besonderes Augenmerk musst du auf die Terminierung richten, also den Fall, bei dem deine Funktion NICHT rekursiv sich selbst auf ruft, sondern ihr Teilproblem vollständig lösen kann. Ohne eine Terminierung würde die Funktion unendlich lange sich selbst aufrufen.
Du schreibst also eine Funktion, die einen Teil des Problems selbst löst und sich mit dem Resetproblem erneut (rekursiv) aufruft. Dann wird die eigene Lösung und der Rückgabewert des rekursiven Aufrufs kombiniert und zurück gegeben. Wenn es kein Resetproblem mehr gibt, sind wir fertig (terminiert) und geben nur das eigene Ergebnis zurück.
Bottle: Micro Web Framework + Development Blog
Also in etwa so ^^:
Code: Alles auswählen
(lambda f: lambda x: f(f, x))(lambda f, x: x and f(f, x[1:])+[x[0]])
Das Leben ist wie ein Tennisball.
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Wir sind hier nicht bei lisp (und selbst ich hab Probleme, das da auf Anhieb zu verstehen O.o)
Bottle: Micro Web Framework + Development Blog
Eine mögliche Lösung habe ich gerade mal geschrieben, aber es wäre ja zu einfach, wenn ich dir die jetzt posten würde
Darum hab ich mal die wichtigen Codestellen mit ??? ersetzt
Da hast du als Grundstruktur schon gegeben, dass sich i jedes mal um eins erhöht (und logischerweise damit die Abbruchbedingung zusammenhängt) und du in jedem Schritt L veränderst.
Dazu lösche ich die ursprünglichen Elemente von hinten angefangen und füge sie wieder ganz am Ende der Liste hinzu. (L.append() und L.pop() sind da praktische Funktionen)
Also sieht der Durchgang mit 3 Elementen wie folgt aus:
Der 1. (i=0) Schritt ist zwar unnötig, da er nichts verändert, aber der Code ist denke ich einfacher, wenn man den Fall nicht berücksichtigt.
Ich hoffe das hilft dir etwas mehr als EyDus Vorschlag
Darum hab ich mal die wichtigen Codestellen mit ??? ersetzt
Code: Alles auswählen
def reverse(L, i=0):
if ???: # Abbruchbedingung
return L # Die umgekehrte Liste zurückgeben
else:
??? # Elemente schrittweise in umgekehrte Reihenfolge bringen
return reverse(L, i+1)
Dazu lösche ich die ursprünglichen Elemente von hinten angefangen und füge sie wieder ganz am Ende der Liste hinzu. (L.append() und L.pop() sind da praktische Funktionen)
Also sieht der Durchgang mit 3 Elementen wie folgt aus:
Code: Alles auswählen
i = 0:
L = [1, 2, 3] # 3 wurde gelöscht und wieder hinten angehangen (kein Effekt)
i = 1
L = [1, 3, 2] # 2 wurde gelöscht und wieder hinten angehangen
i = 2
L = [3, 2, 1] # 1 wurde gelöscht und wieder hinten angehangen
Ich hoffe das hilft dir etwas mehr als EyDus Vorschlag
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Der i Parameter ist eigentlich überflüssig, es sei denn, in-place ist Bedingung Die Liste oder Teilliste ist alles, was man als Input braucht.
Zuletzt geändert von Defnull am Freitag 5. März 2010, 14:15, insgesamt 1-mal geändert.
Bottle: Micro Web Framework + Development Blog
Code: Alles auswählen
def reversed(l):
if l:
return [l.pop()] + reversed(l)
return []
print reversed(range(3))
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
@DasIch: Willst du unsere Bemühungen, dem OP etwas bei zu bringen, zur Nichte machen oder hast du einfach nur den Thread nicht gelesen?
Ganz abgesehen davon überschreibst du ein buildin. Böse!
Ganz abgesehen davon überschreibst du ein buildin. Böse!
Bottle: Micro Web Framework + Development Blog
i ist ja strenggenommen auch kein "Input", es soll ja nicht beim Aufruf übergeben werden, sondern nur innerhalb der Funktion überschrieben werden.Defnull hat geschrieben:Der i Parameter ist eigentlich überflüssig, es sei denn, in-place ist Bedingung Die Liste oder Teilliste ist alles, was man als Input braucht.
Es geht bestimmt auch ohne i, aber ich denke die Variante ist relativ verständlich (while-ähnlich) und kommt ohne kompliziertere Gedankenvorgänge aus.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Also ich finde die Idee mit dem ``i`` jetzt nicht so sonderlich toll, um Rekursion zu verstehen. Zudem CPython keine Endrekursion optimiert bringt das ``i`` tatsächlich überhaupt nichts. Dadurch wird man eher durch irgendwelche Indexerei abgelenkt als durch die teilweise zerlegung in einfachere Probleme.Nocta hat geschrieben:Ich hoffe das hilft dir etwas mehr als EyDus Vorschlag
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Vielen Dank für euere hilfreichen Antworten!! Mit dem Code von Nocta hab ich jetzt genau, was ich wollte...
Wobei mich der Interesse halber schon noch interessieren würde, wie die Lösung von EyDu arbeitet....der kann ich als Anfänger leider garnicht folgen
Vielen Dank euch allen und ein schönes Wochenende!!
Wobei mich der Interesse halber schon noch interessieren würde, wie die Lösung von EyDu arbeitet....der kann ich als Anfänger leider garnicht folgen
Vielen Dank euch allen und ein schönes Wochenende!!
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Oder nach der Lösung das Ergebnis an die vorherige Rekursionsebene zurückliefern solltest (Wie beim Mergesort iirc). Gibt also zwei Möglichkeiten: Auf dem Weg in die Tiefe "Arbeit verrichten" (Qicksort) oder auf dem Weg zurück.Defnull hat geschrieben: Jeder Schritt muss dich näher ans Ziel bringen. Das heißt, das du in jeder Rekursionsstufe einen Teil des Problems lösen musst und nur den Rest rekursiv weiter reichen darfst.