Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

rekursiver Generator

2 views
Skip to first unread message

Thomas Orgelmacher

unread,
Oct 10, 2009, 6:34:53 AM10/10/09
to
Hallo zusammen!

Ich hoffe 'mal, das ist jetzt keine FAQ. Aber als Python-Neuling
komme ich hier absolut nicht weiter:

def t(n):
yield n
if(n < 10):
t(n + 1)

for i in t(0):
print(i)

Warum tut das so nicht? Wenn ich das richtig verstanden habe,
wird der komplette Zustand einer Funktion bei einem yield gesichert
und beim nᅵchsten "Aufruf" wird nach dem yield weitergemancht.
Das funktioniert auch soweit (ich habe testhalber 'mal nach jeder
Zeile ein print eingefᅵgt), aber die Rekursion funktioniert nicht.


Gruᅵ,

Orgel

--
I have seen things you lusers would not believe. I've seen Sun
monitors on fire off the side of the multimedia lab. I've seen
NTU lights glitter in the dark near the Mail Gate. All these
things will be lost in time, like the root partition last week.

Diez B. Roggisch

unread,
Oct 10, 2009, 6:39:50 AM10/10/09
to
Thomas Orgelmacher schrieb:

> Hallo zusammen!
>
> Ich hoffe 'mal, das ist jetzt keine FAQ. Aber als Python-Neuling
> komme ich hier absolut nicht weiter:
>
> def t(n):
> yield n
> if(n < 10):
> t(n + 1)
>
> for i in t(0):
> print(i)
>
> Warum tut das so nicht? Wenn ich das richtig verstanden habe,
> wird der komplette Zustand einer Funktion bei einem yield gesichert
> und beim nᅵchsten "Aufruf" wird nach dem yield weitergemancht.
> Das funktioniert auch soweit (ich habe testhalber 'mal nach jeder
> Zeile ein print eingefᅵgt), aber die Rekursion funktioniert nicht.

Weil du immer wenn du einen Wert zurueckgeben willst ein yield brachst.
Woher soll python das sonst wissen?

def t(n):
yield n
if n < 10: # keine Klammern, wir sind hier nicht in C/Java/*
yield t(n+1)


Diez

Thomas Orgelmacher

unread,
Oct 10, 2009, 7:55:21 AM10/10/09
to
Diez B. Roggisch schrieb:

> Weil du immer wenn du einen Wert zurueckgeben willst ein yield brachst.
> Woher soll python das sonst wissen?

Naja, durch die Rekursion sollte man ja wieder am ersten yield
vorbei kommen?

> def t(n):
> yield n
> if n < 10: # keine Klammern, wir sind hier nicht in C/Java/*

Erwischt...

> yield t(n+1)

ᅵhm, sicher?

| orgel@think3:~> ./t.py
| 0
| <generator object t at 0xb7e2fb44>

Ich steh' immer noch auf'm Schlauch...

Mick Krippendorf

unread,
Oct 10, 2009, 8:11:40 AM10/10/09
to
Hallo.

Thomas Orgelmacher schrieb:


>
> def t(n):
> yield n
> if(n < 10):
> t(n + 1)
>
> for i in t(0):
> print(i)
>
> Warum tut das so nicht? Wenn ich das richtig verstanden habe,
> wird der komplette Zustand einer Funktion bei einem yield gesichert
> und beim nᅵchsten "Aufruf" wird nach dem yield weitergemancht.


Generatoren yield nur zu ihrem Aufrufer zurᅵck. Alles weitere muss man
von Hand machen:

def t(n):
yield n
if(n < 10):

for each in t(n + 1):
yield each

for i in t(0):
print(i)


Gruᅵ,
Mick.

Diez B. Roggisch

unread,
Oct 10, 2009, 9:22:18 AM10/10/09
to
Thomas Orgelmacher schrieb:

> Diez B. Roggisch schrieb:
>
>> Weil du immer wenn du einen Wert zurueckgeben willst ein yield brachst.
>> Woher soll python das sonst wissen?
>
> Naja, durch die Rekursion sollte man ja wieder am ersten yield
> vorbei kommen?
>
>> def t(n):
>> yield n
>> if n < 10: # keine Klammern, wir sind hier nicht in C/Java/*
>
> Erwischt...
>
>> yield t(n+1)
>
> ᅵhm, sicher?
>
> | orgel@think3:~> ./t.py
> | 0
> | <generator object t at 0xb7e2fb44>
>
> Ich steh' immer noch auf'm Schlauch...

Arg, Mist. Man sollte testen :)

Man muss natuerlich auch alle Elemente des Rekursiven Aufrufes
aufzaehlen & zurueckgeben.

def t(n):
yield n
if n < 10:

for i in t(n+1):
yield i


Das ist ein Muste das oft vorkommt, und darum haeufiger Leute danach
fragen, ob man nicht sowas einfuehren koennte:


yield_all t(n+1)

Aber bisher ist das immer abgelehnt worden.

Diez

Thomas Orgelmacher

unread,
Oct 10, 2009, 9:35:13 AM10/10/09
to
Mick Krippendorf schrieb:

> Generatoren yield nur zu ihrem Aufrufer zurᅵck. Alles weitere muss man
> von Hand machen:

Ah, jetzt, ja... Groschen fᅵllt...

Danke!

Georg Brandl

unread,
Oct 10, 2009, 12:31:56 PM10/10/09
to
Diez B. Roggisch schrieb:

> Man muss natuerlich auch alle Elemente des Rekursiven Aufrufes
> aufzaehlen & zurueckgeben.
>
> def t(n):
> yield n
> if n < 10:
> for i in t(n+1):
> yield i
>
>
> Das ist ein Muste das oft vorkommt, und darum haeufiger Leute danach
> fragen, ob man nicht sowas einfuehren koennte:
>
>
> yield_all t(n+1)
>
> Aber bisher ist das immer abgelehnt worden.

Sieht im Prinzip gar nicht *so* schlecht aus, soweit ich mich erinnere,
war die letzte Diskussion über PEP 380 recht positiv:

http://www.python.org/dev/peps/pep-0380/

Das (als "yield from") könnte es also durchaus in 2.7 bzw. 3.2 schaffen.

Georg

Thomas Mlynarczyk

unread,
Oct 10, 2009, 4:00:48 PM10/10/09
to
Diez B. Roggisch schrieb:

> def t(n):
> yield n
> if n < 10:
> for i in t(n+1):
> yield i

Laut Ausprobieren liefert das die Zahlen von 0 bis 10. Aber das hier:

def u():
i = 0
while i <= 10:
yield i
i += 1

tut's doch auch, bzw. noch einfacher:

xrange( 11 )

Ich verstehe daher den Sinn der Rekursion hier nicht ganz.

Gruᅵ,
Thomas


--
Ce n'est pas parce qu'ils sont nombreux ᅵ avoir tort qu'ils ont raison!
(Coluche)

Marek Kubica

unread,
Oct 11, 2009, 4:46:39 AM10/11/09
to
Hallo,

On Sat, 10 Oct 2009 22:00:48 +0200
Thomas Mlynarczyk <tho...@mlynarczyk-webdesign.de> wrote:

> Laut Ausprobieren liefert das die Zahlen von 0 bis 10. Aber das hier:
>
> def u():
> i = 0
> while i <= 10:
> yield i
> i += 1
>
> tut's doch auch, bzw. noch einfacher:
>
> xrange( 11 )
>
> Ich verstehe daher den Sinn der Rekursion hier nicht ganz.

Natürlich *geht* das, aber der Sinn dieser Rekursion ist Rekursion zu
verstehen.

grüße,
Marek

Thomas Orgelmacher

unread,
Oct 11, 2009, 7:15:37 AM10/11/09
to
Thomas Mlynarczyk schrieb:

> Ich verstehe daher den Sinn der Rekursion hier nicht ganz.

Der lag ganz einfach darin, daᅵ ich da ein Verstᅵndnisproblem
mit yield im Kontext einer Rekursion hatte.
Der von mir gepostete Codeschnipsel ist auch nur eine auf's
Wesentliche heruntergebrochene Version einer deutlich grᅵᅵeren
Funktion. Und die ist nicht mit "xrange(11)" zu realisieren.

Gruᅵ,

Dietmar Schwertberger

unread,
Oct 11, 2009, 11:26:17 AM10/11/09
to
Thomas Orgelmacher schrieb:

> Thomas Mlynarczyk schrieb:
>
>> Ich verstehe daher den Sinn der Rekursion hier nicht ganz.
>
> Der lag ganz einfach darin, daᅵ ich da ein Verstᅵndnisproblem
> mit yield im Kontext einer Rekursion hatte.
> Der von mir gepostete Codeschnipsel ist auch nur eine auf's
> Wesentliche heruntergebrochene Version einer deutlich grᅵᅵeren
> Funktion. Und die ist nicht mit "xrange(11)" zu realisieren.

Allgemein wᅵrde ich zu diesem Thema noch anmerken, daᅵ es
vermutlich nicht allzuviel Sinn macht, rekursive Generatoren in
groᅵem Stil zu verwenden, da sie Performance kosten (jeder Aufruf
muᅵ alle Daten durchreichen).

Mich wᅵrde ein Beispiel interessieren, wo sie wirklich Sinn machen,
falls es ein solches gibt...


Gruᅵ,

Dietmar

Mick Krippendorf

unread,
Oct 11, 2009, 12:30:24 PM10/11/09
to
Hallo.

Dietmar Schwertberger schrieb:


> Allgemein wᅵrde ich zu diesem Thema noch anmerken, daᅵ es
> vermutlich nicht allzuviel Sinn macht, rekursive Generatoren in
> groᅵem Stil zu verwenden, da sie Performance kosten (jeder Aufruf
> muᅵ alle Daten durchreichen).
>
> Mich wᅵrde ein Beispiel interessieren, wo sie wirklich Sinn machen,
> falls es ein solches gibt...


Bei mir werkeln sie sich in einem Spielzeug-Prolog-Interpreter ab, den
ich aber gerade auf Continuation Style Passing + Tail Call Optimization
umbaue (s.a. http://www.python-forum.de/topic-20510.html).

Gruᅵ,
Mick.

0 new messages