Python Referenzen und Objektkopien?
ChatGPT und mein Pythonbuch sagen folgendes:
„In Python werden Objekte durch Referenzen verwaltet, die auf den Speicherbereich zeigen, in dem das Objekt gespeichert ist. Wenn ein Objekt über eine Referenz zugewiesen wird, wird der Speicherplatz für das Objekt reserviert und die Referenz zeigt auf diesen Speicherbereich. Wenn auf denselben Wert bereits von einer anderen Referenz verwiesen wird, zeigt diese Referenz auf dasselbe Objekt/Speicherbereich.“
Aber danach steht in meinem Pythonbuch der Code am Ende dieser Nachricht.
Und über dem Code stand, dass mit diesem y.append(i) eine echte Kopie von x erstellen kann. Aber da ja schon x auf die Liste verweist hätte man nach dem .append() ja zwei Referenzen. Nämlich x und y. Also müsste Python laut der ersten Aussage doch mit beiden Referenzen auf ein und dasselbe Objekt verweisen. Dann wäre es aber keine Kopie mehr, sondern das gleiche Objekt.
Ich hoffe, dass ich mein Problem irgendwie erklären konnte.
LG Code Snake 🙂
import copy
x = [23, "hallo", -7.5]
y = []
for i in x:
y.append(i)
print("dasselbe Objekt:", x is y)
print("gleicher Inhalt:", x == y)
print()
x = (23, ["Berlin", "Hamburg"], -7.5, 12.67)
y = copy.deepcopy(x)
print("dasselbe Objekt:", x is y)
print("gleicher Inhalt:", x == y)
3 Antworten
Y zeigt dann ja auf die Kopie, und das ist dann nicht mehr das gleiche Objekt.
Hier ein Beispiel:
x = 42
y = 56
print (f"x:{x}, y:{y}, identisch:{x is y}")
y = 42
print (f"x:(x), y:{y}, identisch:{x is y}")
Beim ersten Vergleich der Objekte kommt False raus beim zweiten True.
Zahlen werden meist anders behandelt als strukturierte Objekte.
Der Punkt ist folgnder, wenn Du:
liste1=[......]
liste2=liste1
machst, dann hast Du 2 Namen für das gleiche Objekt.
In Deinem Code wird mit y=[] aber explizit eien neue leee Liste erzeugt und danach Item für Item angehängt.
Zu Überwachen, daß diese Liste nach jeder möglichen Änderung jetzt irgendeiner anderen entspricht ist nicht stemmbar - das hat unter anderem auch damit zu tun, daß Listen mutable sind. Bei Imutables ergibt sich das Problem nicht.
Der nächste Aspekte ist dann noch der Unterschied zwischen eienr Shallow und einer deep copy, KuarThePirat hat da schon was verlinhkt.
Einw einfache Shallow Copy lässt sich auch mit Slicing realisieren:
l2=l1[:]
Ich weiß nicht, ob ich dein Problem wirklich verstanden habe, aber vielleicht sorgt dieser Blog Artikel hier für etwas mehr Aufklärung: https://bodo-schoenfeld.de/der-unterschied-von-copy-und-deepcopy-in-python/
In deinem Beispiel sind x und y von Anfang an unterschiedliche Objekte im Speicher, daher verstehe ich nicht, was Du versuchst mit dem Code zu zeigen.
Ich verstehe halt nicht, warum x und y zwei unterschiedliche Objekte referenzieren. Denn in meinem Pythonbuch steht ja:
„Wenn ein Objekt über eine Referenz zugewiesen wird, wird der Speicherplatz für das Objekt reserviert und die Referenz zeigt auf diesen Speicherbereich. Wenn auf denselben Wert bereits von einer anderen Referenz verwiesen wird, zeigt diese Referenz auf dasselbe Objekt/Speicherbereich.“
Die neue Referenz auf die Liste im Codebeispiel ist ja y. Aber da x ja schon vorher auf die Liste verwiesen hat, müssten dann doch beide auf das gleiche Objekt zeigen. Also wäre es keine Kopie.
Gegenfrage? Wie könnten sie überhaupt auf das gleiche Objekt referenzieren. Du erstellt nie eine Referenz. Gleich zu Beginn hast Du zwei unterschiedliche Objekte mit der Zuweisung y = [] erstellt.
Eine Referenz sähe so aus:
x = [23, "hallo", -7.5]
y = x
y.append("Test")
print("dasselbe Objekt:", x is y)
print("gleicher Inhalt:", x == y)
Aber nach dem y.append(i) sind beide Objekte doch vom Inhalt gleich. Dann wird laut meinem Pythonbuch auf den gleichen Speicherplatz sprich auf das selbe Objekt verwiesen. Von beiden Referenzen.
Nein, gleicher Inhalt heißt nicht, dass das Objekt gleich ist.
Aber das steht in meinem Pythonbuch:
“ In Python werden Objekte durch Referenzen verwaltet, die auf den Speicherbereich zeigen, in dem das Objekt gespeichert ist. Wenn ein Objekt über eine Referenz zugewiesen wird, wird der Speicherplatz für das Objekt reserviert und die Referenz zeigt auf diesen Speicherbereich. Wenn auf denselben Wert bereits von einer anderen Referenz verwiesen wird, zeigt diese Referenz auf dasselbe Objekt/Speicherbereich.“
Und das ist ja hier der Fall.