Seite 1 von 1
liste.append(liste)
Verfasst: Samstag 3. Mai 2008, 21:25
von sehbaer
Liebe Pythonenbeschleuniger,
Nachdem der neue Herr Ubuntu mich sehr geärgert hatte und ich mittlerweile auf Sidux umgefummelt habe, konnte ich mich wieder dem Erlernen von Python zuwenden.
Heute habe ich ein bischen der Liste auf den Schlangenzahn gefühlt und dabei ein Fragezeichen in mir erzeugt:
Wenn man einer Liste sich selbst zuweist, taucht in dieser Liste der Listeneintrag [...] auf. Wie ist das zu interpretieren?
Was genau bedeutet [...]?
Wenn ich das richtig verstanden habe, dann wird die Referenz der Liste übergeben und nicht die Liste an sich. Das ergibt einen Verweis auf sich selbst also eine unendliche Rekursion, oder? Aber warum akzeptiert Pyton das ungerührt? Sollte da nicht irgendwas überlaufen, wenn es wirklich unendlich ist (Stack, Speicher etc.)? Ist das völlig sinnbefreit, oder gibt es da für eine wirkliche Anwendung?
>>> liste = []
>>> liste.append(liste)
>>> liste
[[...]]
>>> liste =[1]
>>> liste.append(liste)
>>> liste
[1, [...]]
>>> liste.append(liste)
>>> liste
[1, [...], [...]]
>>>
man kann auch in scheinbar unbegrenzter Tiefe darauf indizieren:
>>> liste[1][2][2][1][1][0]
1
Verfasst: Samstag 3. Mai 2008, 23:02
von EyDu
Das [...] bedeutet lediglich, dass der Interpreter die unendliche Rekursion erkannt hat. Und ein Stacküberlauf tritt natürlich nicht auf, weil wie du ja schon erkannt hast, Python nur mit Referenzen arbeitet und nicht die ganze Liste kopiert wird. Wende doch mal "len" auf "liste" an. Wie du siehst, ist diese nicht unendlich lang.
Verfasst: Sonntag 4. Mai 2008, 06:20
von BlackJack
@sehbaer: Warum sollte Python das nicht akzeptieren? Es ist gültiger Quelltext, die Semantik ist definiert, und schaden richtet es auch keinen an.
Mal umgekehrt betrachtet: Wenn Python gegen so etwas was haben sollte, wie sieht dann der Code aus, eine Rekursion zu erkennen? So eine rekursive Datenstruktur muss ja nicht so direkt sein. Mit zwei Listen:
Code: Alles auswählen
In [137]: a = []
In [138]: b = [a]
In [139]: a.append(b)
In [140]: a
Out[140]: [[<Recursion on list with id=156082476>]]
In [141]: b
Out[141]: [[<Recursion on list with id=156905036>]]
Aber da können noch beliebig viele andere Listen und auch noch andere Elemente involviert sein, und man müsste dann mit jedem `list.append()` und jeder Indexzuweisung immer die alle beteiligten Listen rekursiv durchgehen um zu prüfen, ob da irgend wo eine Rekursion ist.
Ausserdem kann man das durchaus absichtlich machen wollen. Die "leichtgewichtigste" Art einen Graphen darzustellen, ist eine Liste mit einer Liste für jeden Knoten, die für jede Kante einen Verweis auf die entsprechende andere Knotenliste enthält. Und wenn in dem Graphen Kreise sind, hat man auch rekursive Listenbeziehungen.
moinsen
Verfasst: Sonntag 4. Mai 2008, 08:09
von sehbaer
Moinsen, liebe Pythonauten!
@ Eydu: Klar hat die Liste in meinem Beipiel da oben nur 3 Elemente. Aber die auf liste referenzierten Elemente haben doch eine unendliche Rekursionstiefe. So ein klein bichschen unendlich finde ich das schon

Mein Denkfehler war wohl das diese unendliche Rekursionstiefe erst beim Indizieren zur Laufzeit entsteht und die liste an sich ganz lieb ist.
@Blackjack: Stimmt auffallend. Mit dem Kreis wird mir das klar! Danke!
Was sind das für seltsame In[]: und Out[]: in Deinem Code? Wie komme ich an das '[[<Recursion on list with id=047110825>]]. Wenn ich das nachvollziehe gibt mir b ganz nackig in den Interpreter gestellt '[[[..]]]' zurück.
Verfasst: Sonntag 4. Mai 2008, 08:35
von BlackJack
Die ``In […]:``\s und ``Out […]:``\s kommen von
IPython, einer Python-Shell, die ein bisschen mehr kann als die Standard-Python-Shell. Für die etwas ausführlichere Darstellung der Rekursion ist IPython auch verantwortlich.
[OT]: ipython
Verfasst: Sonntag 4. Mai 2008, 10:13
von sehbaer
...kommen wir nun zu etwas ganz anderem:
@ Blackjack: Habe zum Morgenkaffee mit ipython gespielt. ipython mächt Laune und ist das, was ich gesucht habe. Bei meinen bisherigen Antestereien von verschiedenen "Python-Editoren" hatte ich für mich bis dato nur unbefriedigende Lösungen entdeckelt.
Eine Shell mit eingebautem Editor finde ich irgendwie eleganter, als ein Editor mit eingebauter Shell. Mit vim werde ich auch so langsam warm und beginne die Effizienz dieses Urgesteins mehr und mehr zu schätzen. Das ist auch evtl. gut gegen meinen "XP-Mausarm" von der Maloche. Danke für den Tipp!
Verfasst: Sonntag 4. Mai 2008, 11:23
von Leonidas
Du könntest dir auch bPython ansehen, mit PyParsing ist es eine vergleichsweise brauchbarer Interpreter-Aufsatz. Ich habe damit aber auch nur heute morgen gespielt.
Verfasst: Dienstag 3. Februar 2009, 15:08
von nkoehring

bPython ist toll!
