Seite 1 von 1
Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Montag 11. September 2017, 18:31
von Unplayable
Hallo Zusammen,
ich möchte ein Programm schreiben, welches eine neue Liste aus den Zahlen einer liste zurückliefert, die ohne Rest durch eine bestimmte Zahl teilbar sind. Das ist der Code:
Code: Alles auswählen
def listenfilter_teilbar(liste,zahl):
a=[]
if liste==[]:
return a
if liste[0]%zahl==0:
a.append(liste[0])
a = a+listenfilter_teilbar(liste[1:],zahl)
return a
else:
a=a+listenfilter_teilbar(liste[1:],zahl)
beim Ausführen kommt aber jedes Mal der oben angegebene Fehlercode?
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Montag 11. September 2017, 18:59
von Sirius3
@Unplayable: ist Deine Hausaufgabe, Rekursion zu benutzen? Denn hier ist eine rekursive Lösung deutlich komplizierter als eine nicht-rekursive.
Wenn Du eine Fehlermeldung hast, dann ist der sogenannte Traceback genauso wichtig. Dort steht nämlich, wo genau im Programmablauf der Fehler auftritt. So muß jetzt jeder, der Dir helfen will, raten, an welcher Stelle der Fehler genau auftritt.
Erst eine leere Liste zu erstellen, um dann diese leere Liste mit einer anderen Liste per + zu kombinieren, ist ziemlich umständlich.
Kommt der Programmablauf ans Ende einer Funktion, ohne return, so wird implizit None zurückgegeben.
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Montag 11. September 2017, 19:09
von Unplayable
Ja ist die Aufgabe, das ganze rekursiv zu gestalten. Die Liste die übergeben wird, soll dabei nicht verändert werden, weshalb ich die Liste a erstellt habe.
Hier ist der Fehlercode in der Shell. Es muss also im Else Zweig irgendwas schief gelaufen sein?:
>>> listenfilter_teilbar([2,4,8],2)
[2, 4, 8]
>>> listenfilter_teilbar([2,4,8,15],2)
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
listenfilter_teilbar([2,4,8,15],2)
File "B:/Info 11 LK/AB08.py", line 21, in listenfilter_teilbar
a = a+listenfilter_teilbar(liste[1:],zahl)
File "B:/Info 11 LK/AB08.py", line 21, in listenfilter_teilbar
a = a+listenfilter_teilbar(liste[1:],zahl)
File "B:/Info 11 LK/AB08.py", line 21, in listenfilter_teilbar
a = a+listenfilter_teilbar(liste[1:],zahl)
TypeError: can only concatenate list (not "NoneType") to list
>>>
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Montag 11. September 2017, 19:19
von Sirius3
Dass man die Liste nicht verändern soll, bedeutet noch nicht, dass man `a` so kompliziert benutzen muß. Zu Deinem Problem habe ich ja schon geantwortet.
Dann kann ich ja die nicht-rekursive Lösung posten:
Code: Alles auswählen
def listenfilter_teilbar(liste, zahl):
return [num for num in liste if liste % zahl == 0]
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Montag 11. September 2017, 19:24
von Unplayable
Ohje wie blöd von mir. So spät sollte ich wohl nicht mehr programmieren. Hab mir aber mit dem Prinzip der Rekursion etwas schwer getan. Nachdem ich return a hinzugefügt habe, läuft es. Vielen Dank

Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Montag 11. September 2017, 19:28
von Unplayable
Wie könnte man das mit a denn einfacher machen?
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Dienstag 12. September 2017, 07:25
von Sirius3
@Unplayable: Du initialisiert a als leere Liste, so dass das Ergebnis jeder Operation in den if-Zweigen schon feststeht:
Code: Alles auswählen
def listenfilter_teilbar(liste, zahl):
if not liste:
# Liste ist leer -> Ende der Rekursion
return []
# Erzeuge die Ergebnisliste, je nachdem, ob das erste Element teil davon ist, oder nicht
if liste[0]%zahl==0:
result = [liste[0]]
else:
result = []
# Füge den Rest zum Ergebnis hinzu
result.extend(listenfilter_teilbar(liste[1:], zahl))
return result
Diese Funktion erzeugt immer noch für jedes Element der Eingangsliste eine neue Liste (aber immerhin nicht 2 wie bei Dir) und kopiert alle Listenelemente n^2/2 mal. Filtern ist einfach kein Problem, das man rekursiv löst. Lernen an Beispielen ist zwar gut, aber an Beispielen, an denen Rekursion sinnlos ist, führt nur dazu, dass irgendjeman denken könnte, ähnliche Probleme würden auch so gelöst werden.
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Dienstag 12. September 2017, 09:04
von kbr
@Sirius3: der TE hat Dein nicht-rekursives Beispiel vermutlich nicht ausprobiert, sonst wäre ihm der Fehler in der Condition aufgefallen, die 'if not num % zahl' lauten müsste.
@Unplayable: Rekursion ist in Python zwar möglich, aber man sollte wissen, dass die damit verbundenen Funktionsaufrufe teuer sind sowie die Rekursionstiefe begrenzt ist. Wenn sich eine rekursive Lösung auch interativ formulieren lässt (und das ist praktisch immer der Fall), dann ist dieser Lösungsweg in Python oftmals die bessere Wahl.
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Dienstag 12. September 2017, 10:06
von Kniffte
kbr hat geschrieben:@Sirius3: der TE hat Dein nicht-rekursives Beispiel vermutlich nicht ausprobiert, sonst wäre ihm der Fehler in der Condition aufgefallen, die 'if not num % zahl' lauten müsste.
wenn ich mich nicht irre ^^
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Dienstag 12. September 2017, 11:51
von kbr
@Kniffte: Du irrst Dich. Ich meinte, was ich schrieb

Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Dienstag 12. September 2017, 12:36
von Kniffte
@kbr
ahjo...jetzt hab ich´s...ich bin davon ausgegangen, dass du nur das 'liste' korrigieren wolltest und das '== 0' nur nicht geschrieben hast.
Aber so ergibt´s natürlich Sinn...sorry
Code: Alles auswählen
def listenfilter_teilbar(liste, zahl):
return [num for num in liste if not num % zahl]
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Dienstag 12. September 2017, 19:15
von Unplayable
Sirius3 hat geschrieben:@Unplayable: Du initialisiert a als leere Liste, so dass das Ergebnis jeder Operation in den if-Zweigen schon feststeht:
Code: Alles auswählen
def listenfilter_teilbar(liste, zahl):
if not liste:
# Liste ist leer -> Ende der Rekursion
return []
# Erzeuge die Ergebnisliste, je nachdem, ob das erste Element teil davon ist, oder nicht
if liste[0]%zahl==0:
result = [liste[0]]
else:
result = []
# Füge den Rest zum Ergebnis hinzu
result.extend(listenfilter_teilbar(liste[1:], zahl))
return result
Diese Funktion erzeugt immer noch für jedes Element der Eingangsliste eine neue Liste (aber immerhin nicht 2 wie bei Dir) und kopiert alle Listenelemente n^2/2 mal. Filtern ist einfach kein Problem, das man rekursiv löst. Lernen an Beispielen ist zwar gut, aber an Beispielen, an denen Rekursion sinnlos ist, führt nur dazu, dass irgendjeman denken könnte, ähnliche Probleme würden auch so gelöst werden.
Leider verstehe ich Zeile 11 deines Codes überhaupt nicht

. Ich tu mir mit der Rekursiven Funktion irgendwie total schwer. Gibt es irgendwo ein Tutorial, welches einem diese Funktion einfach erklärt? Braucht man sowas in Python oft?
Re: Rekursion mit Liste: Error: can only concatenate list (not "NoneType") to list
Verfasst: Dienstag 12. September 2017, 19:35
von Sirius3
@Unplayable: was verstehst Du denn an der Zeile 11 nicht? Wie kbr schon geschrieben hat, braucht man Rekursion fast nie. Eigentlich ist da auch nicht viel dran. Rekursion heißt einfach, eine Funktion ruft sich selbst mit veränderten Parametern auf, bis eine Abbruchbedingung erfüllt wird.