Seite 1 von 1

mir unerklärliche Zuweisung

Verfasst: Samstag 24. Oktober 2015, 22:26
von kodela
Hallo,

bin gerade dabei, mich in die Geheimnisse von Python einzuarbeiten. Sagt jetzt bitte keiner, da gäbe es keine Geheimnisse. Das ist sicher richtig, aber für mich gibt es eben welche.

Für mein erstes Modul habe ich nach Beispielen gesucht und bin dabei auf diese Seite gestoßen. Dort findet sich folgender Code für die Berechnung einer Fibonacci-Folge:

Code: Alles auswählen

def fib(n): # gib die Fibonacci-Folge zurück bis n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result
Was bewirkt der Code in den Zeilen 3 und 6, also a, b = 0, 1 und a, b = b, a+b ?

Nach der Initialisierung in Zeile 3 ist a == 0 und b == 1. Warum wurde b der Wert 1 zugewiesen? Weil das die erste Fibonacci-Zahl ist, aber die Zuweisung sieht doch anders aus.

Ähnlich geht es in Zeile 6 weiter, in b sind die Fibonacci-Zahlen und in a die jeweils vorhergehende Fibonacci-Zahl.

Trotz allem Suchens habe ich für diese Art der Zuweisung nichts gefunden, bin mir aber sicher dass es irgend wo erklärt ist.

Kann mir bitte jemand auf die Sprünge helfen?

MfG, kodela

Re: mir unerklärliche Zuweisung

Verfasst: Samstag 24. Oktober 2015, 22:45
von Sirius3
@kodela: das nennt sich "tuple unpacking", es wird ein Tuple b, a+b erzeugt und in die beiden Variablen a und b entpackt.

Re: mir unerklärliche Zuweisung

Verfasst: Samstag 24. Oktober 2015, 22:59
von pillmuncher
Zu dem, was Sirius3 schin geschrieben hat: der Komma-Operator bindet stärker, als der Zuweisungsoperator. Wenn man die Klammerung explizit macht, sieht man besser, was passiert:

Code: Alles auswählen

In [1]: (a, b) = (0, 1)

In [2]: (a, b) = (b, a + b)

In [3]: a, b
Out[3]: (1, 1)
Der Komma-Operator dient dazu, Tupel zu erzeugen:

Code: Alles auswählen

n [4]: xs = 1,

In [5]: xs
Out[5]: (1,)

In [6]: xs[0]
Out[6]: 1

In [7]: x, = xs

In [8]: x
Out[8]: 1
Die Klammern braucht man nur zur Disambiguierung. In dem Fibonacci-Programm wurden sie weggelassen, weil da nichts zweideutig ist.

Re: mir unerklärliche Zuweisung

Verfasst: Sonntag 25. Oktober 2015, 00:01
von kodela
@Sirius3
@pillmuncher

Danke vorab. Das muss ich aber erst verdauen. Melde mich dann wieder.

MfG, kodela

PS:

Der Hinweis mit der Klammerung hat gezündet. Nochmals vielen Dank!

Re: mir unerklärliche Zuweisung

Verfasst: Sonntag 25. Oktober 2015, 00:44
von kodela
Hallo,

hier eine Zusammenfassung:

Das Konstrukt a, b = 0, 1 steht für einen Tupel mit den beiden Werten a und b, wobei a mit 0 und b mit 1 initialisiert werden.

Besser ist dies mit Klammern zu erkennen: (a, b) = (0, 1)

In der Schleife wird bei jedem Durchlauf mit (a, b) = (b, a + b) der Wert b in a übernommen und der ursprüngliche Wert von a wird zu b aufaddiert.

Würde man a und b als eigenständige Variable definieren, müsste man bei der Anpassung in der Schleife a temporär zwischenspeichern. Das sähe dann so aus:

Code: Alles auswählen

# Initiqalisierung
a = 0
b = 1

# Anpassung in der Schleife
t = a
a = b
b += t
Durch die Zusammenfassung von a und b in einem Tupel erübrigt sich eine Zwischenspeicherung, der Code ist kompakter und sicherlich auch eleganter.

Nochmals vielen Dank für Eure Aufklärung.

MfG, kodela

Re: mir unerklärliche Zuweisung

Verfasst: Sonntag 25. Oktober 2015, 08:09
von bwbg
kodela hat geschrieben:[...]
Das Konstrukt a, b = 0, 1 steht für einen Tupel mit den beiden Werten a und b, wobei a mit 0 und b mit 1 initialisiert werden.
[...]
Genaugenommen erzeugt die rechte Seite der Zuweisung das tuple und die linke Seite nimmt dieses wieder auseinander (unpacking). Das funktioniert nicht nur mit tuples sondern mit jeder Sequenz (tuples, lists, iterators, ...). Wichtig ist, dass die linke Seite der Zuweisung alle Elemente abdecken kann.

Häufig findet man beim unpacking einen Unterstrich/underscore (_). Im Grunde eine normale Zuweisung. _ ist ein gültiger Name, signalisiert jedoch, dass man diesen Wert nicht benötigt:

Code: Alles auswählen

>>> _, two, _ = range(1, 4)
>>> two
2
>>> _
3