Seite 1 von 1

[Sinn/Unsinn] Frage zu Generatoren

Verfasst: Dienstag 21. August 2007, 11:36
von EnTeQuAk
Hallo alle zusammen!

Ich zerbreche mir in letzter Zeit ein wenig den Kopf über die Anwendung eines Generators, im Gegensatz zu einem Iterierbaren Gegenstand.

Zum Hintergrund:

Es gibt einen TokenStream, welcher sich fast exakt wie ein Generator verhällt aber intern mit 'deque's arbeitet, um die Werte darzustellen. Er unterstützt das vorrausschauen und das wieder einspeisen von Tokens.

Nun die Frage: Macht es sinn, die übergebene 'iterable' zu einem Generator zu transferieren

Code: Alles auswählen

self.stack = (x for x in iterable)
Und dadurch aus dem TokenStream wieder einen richtigen Generator zu machen, der nicht sämtliche Werte vorhällt sondern nur mit gerade benötigte beziehungsweise neue Werte, die nicht im vorherigen 'iterable' enthalten waren arbeitet.

Die Frage wollte ich gerne an euch weiterreichen, da es mich interessiert.

Was haltet ihr davon, Vor/Nachteile?

MfG EnTeQuAk

Verfasst: Dienstag 21. August 2007, 12:22
von rayo
Hi

Code: Alles auswählen

(x for x in iterable)
Bei diesem Code seh ich nur unsinn ... Wenn du ja schon ein iterable hast warum nochmals ein iterable daraus machen?

Gruss

Re: [Sinn/Unsinn] Frage zu Generatoren

Verfasst: Dienstag 21. August 2007, 14:05
von Leonidas
EnTeQuAk hat geschrieben:Nun die Frage: Macht es sinn, die übergebene 'iterable' zu einem Generator zu transferieren

Code: Alles auswählen

self.stack = (x for x in iterable)
Und dadurch aus dem TokenStream wieder einen richtigen Generator zu machen, der nicht sämtliche Werte vorhällt sondern nur mit gerade benötigte beziehungsweise neue Werte, die nicht im vorherigen 'iterable' enthalten waren arbeitet.
Nein, das funktioniert doch auch gar nicht (na gut,funktionieren tut es schon, aber es ist mehr oder weniger wirkungslos). Wenn du sagen wir mal, eine Liste zu einem Generator machst, dann muss der Generator doch die Werte die er ausspuckt doch trotzdem noch irgendwo herbekommen - die nimmt er sich aus der Liste. Also hast du damit keine Speicherersparnis (weil die Liste ja mitgespeichert werden muss) und kein Lazy-Verhalten (weil die Liste ja schon im vorhinein feststeht).

Verfasst: Dienstag 21. August 2007, 14:09
von lunar
Generator-Ausdrücke machen nur Sinn, wenn du die Werte des Iterables verändern willst...

Verfasst: Dienstag 21. August 2007, 14:37
von EnTeQuAk
Leonidas hat geschrieben:Nein, das funktioniert doch auch gar nicht (na gut,funktionieren tut es schon, aber es ist mehr oder weniger wirkungslos). Wenn du sagen wir mal, eine Liste zu einem Generator machst, dann muss der Generator doch die Werte die er ausspuckt doch trotzdem noch irgendwo herbekommen - die nimmt er sich aus der Liste. Also hast du damit keine Speicherersparnis (weil die Liste ja mitgespeichert werden muss) und kein Lazy-Verhalten (weil die Liste ja schon im vorhinein feststeht).
Ok
lunar hat geschrieben:Generator-Ausdrücke machen nur Sinn, wenn du die Werte des Iterables verändern willst...
Herzlichen Dank euch dreien!

Mir ging es ja hauptsächlich um die Speicherersparnis. Ich hätte da jetzt eventuell gedacht, das die vorherige Liste irgentwie... keine Ahnung verschwindet oder so xD

Aber das würde ja auch keinen Sinn machen.


Aber wo wir gerade bei dem Thema sind: Generatoren. Sagen wir mal, wir haben folgende Funktion

Code: Alles auswählen

def gen_gen():
    for i in xrange(1, 100):
        yield i*2
Wie genau wird jetzt der Generator abgebildet, wenn er *nicht* Die ausgerechneten Zahlen vorhält. Ungefair so?
(das, was jetzt wie ein Tupel ausschaut, ist jetzt einfach mal mein Generator)

Code: Alles auswählen

(1*2, 2*2, 3*2, 4*2, 5*2)
(usw.)

Oder liege ich da wieder falsch?

MfG EnTeQuAk

Verfasst: Dienstag 21. August 2007, 14:53
von birkenfeld
Der Generator ist ein Python-Objekt, das eine Referenz zu einem Frameobjekt hält (so ein Frame, wie ihn `sys._getframe()` zurückgibt).
Der Frame hat alle Informationen über das Innere der Generatorfunktion, also z.B. Bytecode, momentane Position im Code, Locals, Globals etc.

Instanziert man einen Generator (mit `gen()`), werden erst einmal nur dieses Objekt und der Frame erzeugt. Ruft man dann die Methode `next()` des Generators auf, lässt er diesen Frame dann vom Eval-Loop ausführen. Der läuft dann bis zum nächsten `yield` -- dies unterbricht die Ausführung des Generatorframes und lässt den vorherigen Frame weiterlaufen, etc.

Verfasst: Dienstag 21. August 2007, 15:26
von jens
Ich hab das mal ins wiki gepackt: [wiki]Allgemeine Begriffe#G[/wiki]

Verfasst: Dienstag 21. August 2007, 15:28
von birkenfeld
Nur leider unter dem flscahen Begriff... hier ging es um Generatoren allgemein.