Verständnis yield und Schleife, Rekursion?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mcdwerner
User
Beiträge: 113
Registriert: Donnerstag 7. Juli 2011, 14:27

Hallo!
Seit ein paar Wochen versuche ich, mir autodidaktisch Python beizubringen, nachdem ich mich an ein Permutationsproblem gewagt habe, hab ich mir folgenden Code "geklaut" und versuche nun, ihn zu verstehen:
(das Beispiel und die 'prints' sind von mir, zum Verständnis)
Hoffe ihr könnt ein wenig Licht reinbringen! Fragen, siehe Kommentare unten...

Vielen Dank schonmal,
Werner

Code: Alles auswählen

beispiel = 'Beispiel'
for i in (beispiel[1:]):
    print(i)

def all_perms(str):

    if len(str) <=1:
        yield str
    
    else:
        for perm in all_perms(str[1:]):    # <--- Rekursion, Ja oder Nein?
            print('perm:', perm)

            for i in range(len(perm)+1):
                print('i:', i)
                print('yield:', perm[:i] + str[0:1] + perm[i:])
                yield perm[:i] + str[0:1] + perm[i:]



print(tuple(all_perms('ABC')))
Ausgabe:

e # beispiel[1:] alles ausser dem ersten Buchstaben, eins weiter unten aber nicht, oder doch???
i
s
p
i
e
l
perm: C # <--- Wieso 'C' zuerst? So wie ich das lese müsste es 'B' sein denn: str[1:] heisst doch "alles ausser dem ersten Buchstaben"?
i: 0
yield: BC # Hier wird 'BC' an die erste Schleife zurückgegeben, richtig? Woher weiss das Programm, dass 'BC' nicht zum Ergebnis gehört?
perm: BC
i: 0
yield: ABC
i: 1
yield: BAC
i: 2
yield: BCA
i: 1
yield: CB
perm: CB
i: 0
yield: ACB
i: 1
yield: CAB
i: 2
yield: CBA
('ABC', 'BAC', 'BCA', 'ACB', 'CAB', 'CBA')
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ja, `[1:]` heißt: Beginne bei Index eins (also dem zweiten Element) und gebe von da an alle weiteren Elemente bis zum Schluss aus, bei Strings eben Zeichen.

Der Grund, warum du C zurück kriegst, ist deine Rekursion: `for perm in all_perms()` läuft solange bis die Bedingung zu Beginn der Funktion (`len(str) <= 1`) wahr wird. Dann spuckt er das letzte übrig gebliebene Zeichen aus, da du ja bei jedem Durchlauf jeweils das erste Zeichen wegnimmst.

Den Rest verstehe ich ehrlich gesagt gerade selber nicht. Ich frage mich aber, aus welchem Grund du so ein verworrenes Beispiel benutzt.
BlackJack

@mcdwerner: Du solltest am besten den Ablauf mit den einzelnen Aufrufen und den jeweiligen lokalen Werten auf Papier nachvollziehen.

zu ``perm: C``: Die Ausgabe von C als erstes ist richtig. Schon alleine weil es eben das ist, was ausgegeben wird. ;-)

Der Aufruf ``all_perms('ABC')`` (1. Ebene) läuft in das ``else`` und im Kopf der ``for``-Schleife wird ``all_perms('BC')`` (2. Ebene) aufgerufen. Dieser Aufruf läuft wieder in das ``else`` und dort wird im Kopf der ``for``-Schleife ``all_perms('C')`` (3. Ebene) aufgerufen. Dieser Aufruf liefert das 'C' mit ``yield`` weil `len('C') ≤ 1` gilt. Das 'C' wird also an die ``for``-Schleife in der 2. Aufrufebene weitergereicht, und dort an `perm` gebunden und als erstes in der Schleife mit `print()` ausgegeben.

zu ``yield: BC``: Das gehört zum Ergebnis, aber zu dem in der 2. Aufrufebene und nicht dem in der 1. Aufrufebene. Dort wird es ja noch um das fehlende Element ergänzt, bevor es zum ersten Aufrufer weiter gereicht wird.
mcdwerner
User
Beiträge: 113
Registriert: Donnerstag 7. Juli 2011, 14:27

Danke für die schnellen Antworten :D

Für's erste hab ich's verstanden, um das ganze auf Papier zu bringen ist mir die Funktion im Moment noch zu stark verschachtelt, mit der Rekursion und den beiden for-Schleifen...

Werd mich mal wieder zurück zu den Grundlagen begeben und eine etwas einfachere Funktion entschlüsseln...

But "i'll be back" :wink:

Beste Grüße!
Werner
Newcomer
User
Beiträge: 131
Registriert: Sonntag 15. Mai 2011, 20:41

Ja das hab ich jetzt auch schon verstanden, das rekursive. Wo ich jedoch immer noch kanbbere ist es, ein solches iteratives programm zu schreiben. Das stellt sich als einiges schwerer heraus
Antworten