Man sollte sich dies so vorstellen: In der ersten Zeile des obigen Programms wird die Liste [0, 1, 2, 3] irgendwo im Speicher angelegt, an einer gewissen Speicheradresse (das ist eine gewisse Position im Speichermedium, so wie eine Adresse eine gewisse Position auf der Welt kodiert). Beispielsweise könnte sie an der Speicheradresse 6 stehen:
Die Variable a
wird mit dem Befehl a = [0, 1, 2, 3]
mit dieser Speicheradresse verknüpft (verknüpfen bedeutet, dass der Computer in einer Art Tabelle zu jedem Variablennamen die zugehörige Speicheradresse kennt). Hilfreich ist es, sich diese Verknüpfung wie im obigen Bild als Pfeil auf die entsprechende Position im Speicher vorzustellen. Man sagt deswegen auch, dass a
auf diese Speicheradresse verweist. Der Wert von a
ist das an dieser Speicheradresse gespeicherte Datum [0, 1, 2, 3].
Das obige Bild malt man kurz wie folgt:
a ---------> [0, 1, 2, 3]
Der Befehl b = a
bewirkt, dass b
auf dieselbe Speicheradresse verweist.
a ---------> [0, 1, 2, 3] <--------- b
Der Befehl b[3] = 4
bewirkt das folgende: In der Liste, die sich an der zu b
gehörenden Speicheradresse befindet, wird das Element mit Index 3 auf den neuen Wert 4 gesetzt. Die Speicheradresse der Liste bleibt dabei aber unverändert: Sowohl a
als auch von b
verweisen weiterhin auf diese Speicheradresse.
a ---------> [0, 1, 2, 4] <--------- b
Analoges gilt, wenn wir mit dem Befehl a.append(7)
etwas an die Liste anhängen, die sich unter der zu a
gehörenden Speicheradresse befindet.
a ---------> [0, 1, 2, 4, 7] <--------- b
Dass das bisher Gesagte stimmt, kann man mit Hilfe der Funktion id
(für Identität oder identity) testen, die im Wesentlichen die Speicheradresse einer Variablen liefert: Beispielsweise ist id(a)
die Speicheradresse von a
.
a = [0, 1, 2, 3]
b = a
print(a)
print(id(a))
print(b)
print(id(b))
b[3] = 4
print(a)
print(id(a))
print(b)
print(id(b))
a.append(7)
print(a)
print(id(a))
print(b)
print(id(b))
In diesem Sinne sind Listen mutable (was man deutsch als veränderlich oder per Fremdwort als mutabel bezeichnen mag): Verweist eine Variable, etwa a
, auf eine solche Liste, so kann man diese Liste mit Befehlen wie a[3] = …
oder a.append(…)
oder a.pop(…)
verändern.
Im Gegensatz dazu sind Integers, Floats, Strings, Booleans immutable (also unveränderlich oder immutabel): (Veränderungsbefehle wie bei Listen gibt es nicht.)
a = 3
b = a
b = 4
print(a)
print(id(a))
print(b)
print(id(b))
Der Befehl b = a
bewirkt wieder, dass a
und b
auf dieselbe Speicheradresse verweisen:
a ---------> 3 <--------- b
Da a
als Integer-Variable immutabel ist, kann der Befehl b = 4
den Inhalt der entsprechenden Speicheradresse nicht verändern. Stattdessen wird an einer freien Speicheradresse 4 als Wert der Variablen b
gespeichert.
Wovon hängt es ab, ob ein Datentyp (Beispiele für Datentypen sind strings, integers, floats, Booleans, lists) mutabel oder immutabel ist? Dies ist schlicht von den Entwicklern der Sprache Python so festgesetzt worden.
Will man wirklich eine Kopie einer gegebenen Liste (an einer neuen Speicheradresse) erzeugen, so tut es1) der Befehl b = a[:]
:
a = [0, 1, 2, 3]
b = a[:]
b[3] = 4
print(a)
print(id(a))
print(b)
print(id(b))
a.append(7)
print(a)
print(id(a))
print(b)
print(id(b))
Wer mehr wissen will, mag hier weiterlesen.