Hallo, Ich habe ein Programm geschrieben und finde keine logische Erklärung für den vorhandenen Fehler:
Skript 1:
#define variables
sol_y= [[9,6,1,4],[3,1,2,3]]
new=[]
#new=[[3,1,2,3]]
print("sol_y:"+str(sol_y))
print("---------------")
new.append(sol_y[1]) ######## first step
print("sol_y:"+str(sol_y))
print("new:"+str(new)+"\n")
new[-1].append((8)) ######## second step
print("sol_y:"+str(sol_y))
print("new:"+str(new))
Die Liste sol_y wird nicht verändert, allerdings wird nach "second step" der Wert 8 sowohl an die Liste "new" hinzugefügt (gewollt) als auch an die Liste
"sol_y" (nicht gewollt). Am besten Sie führen das Skript auf Ihrem eigenen PC aus.
Beim Skript 1 mit folgenden Änderungen, tritt der Fehler nicht auf:
Skript 2:
#define variables
sol_y= [[9,6,1,4],[3,1,2,3]]
#new=[]
new=[[3,1,2,3]]
print("sol_y:"+str(sol_y))
print("---------------")
#new.append(sol_y[1]) ######## first step
print("sol_y:"+str(sol_y))
print("new:"+str(new)+"\n")
new[-1].append((8)) ######## second step
print("sol_y:"+str(sol_y))
print("new:"+str(new))
Ich kann mir den Fehler leider nicht erklären. Können Sie mir behilflich sein?
Hier sind noch die Output beider Varianten:
Skript 1:
sol_y:[[9, 6, 1, 4], [3, 1, 2, 3]]
---------------
sol_y:[[9, 6, 1, 4], [3, 1, 2, 3]]
new:[[3, 1, 2, 3]]
sol_y:[[9, 6, 1, 4], [3, 1, 2, 3, 8]]
new:[[3, 1, 2, 3, 8]]
Skript 2:
sol_y:[[9, 6, 1, 4], [3, 1, 2, 3]]
---------------
sol_y:[[9, 6, 1, 4], [3, 1, 2, 3]]
new:[[3, 1, 2, 3]]
sol_y:[[9, 6, 1, 4], [3, 1, 2, 3]]
new:[[3, 1, 2, 3, 8]]
list.append : Merkwürdiger Fehler (Vielleicht Python-Bug)
Nein, das ist kein Python-Fehler. Sondern das übliche Missverständnis, das Listen oder generell alle Objekte durch = kopiert würden. Das ist in Python so nicht. a = irgendwas und b = a bedeuten, dass sowohl a als auch b auf dasselbe(!) irgendwas zeigen. Verändert man das (was bei Listen geht), dann erreicht man über beide Namen a und b das alte, nun veränderte Objekt.
Abhilfe schafft eine explizite Kopie der Liste. Zb mit der Funktion copy.deepcopy. Allerdings ist es meistens eher so, dass man implizit durch zb eine eine List-Komprehension eine neue, veränderte Liste erstellt.
Abhilfe schafft eine explizite Kopie der Liste. Zb mit der Funktion copy.deepcopy. Allerdings ist es meistens eher so, dass man implizit durch zb eine eine List-Komprehension eine neue, veränderte Liste erstellt.
@drummer123: pythontutor.com kann das Verhalten sehr schön visualisieren.
Und bitte setze deinen Code in Zukunft in Codeblöcke, damit man ihn lesen kann.
Und bitte setze deinen Code in Zukunft in Codeblöcke, damit man ihn lesen kann.
-
- User
- Beiträge: 7
- Registriert: Dienstag 10. August 2021, 19:21
Vielen Dank für die Antwort. Pythontutor hat mir sehr geholfen. Ich finde zwar diese Verknüpfungen der Listen merkwürdig, aber so ist das eben...narpfel hat geschrieben: Dienstag 10. August 2021, 21:39 @drummer123: pythontutor.com kann das Verhalten sehr schön visualisieren.
Und bitte setze deinen Code in Zukunft in Codeblöcke, damit man ihn lesen kann.
Ich werde versuchen die Codeblöcke zu verwenden.
-
- User
- Beiträge: 7
- Registriert: Dienstag 10. August 2021, 19:21
Danke für die Antwort. Interessantes Verhalten__deets__ hat geschrieben: Dienstag 10. August 2021, 19:52 Nein, das ist kein Python-Fehler. Sondern das übliche Missverständnis, das Listen oder generell alle Objekte durch = kopiert würden. Das ist in Python so nicht. a = irgendwas und b = a bedeuten, dass sowohl a als auch b auf dasselbe(!) irgendwas zeigen. Verändert man das (was bei Listen geht), dann erreicht man über beide Namen a und b das alte, nun veränderte Objekt.
Abhilfe schafft eine explizite Kopie der Liste. Zb mit der Funktion copy.deepcopy. Allerdings ist es meistens eher so, dass man implizit durch zb eine eine List-Komprehension eine neue, veränderte Liste erstellt.

Das ist bei den meisten Sprachen so. Java, C#, JS zb. Und bei denen, bei denen es anders ist (hauptsächlich C++) gibt es einen ganzen Zoo anderer Probleme. Resourcen management ist schwer.
Und eine kleine Anmerkung: bitte nicht den Beitrag davor im Vollzitat einfügen. Der steht da ja schon.
Und eine kleine Anmerkung: bitte nicht den Beitrag davor im Vollzitat einfügen. Der steht da ja schon.
@drummer123: Das ist in Python nicht nur bei Listen so, sondern bei allen Objekten. `=` verhält sich nicht bei Listen auf magische Weise anders als bei `int`, `str` oder `dict`. Die „korrekte“ Darstellung ist eigentlich diese. Beachte, dass der Pfeil nach `new.append(sol_y[0][0])` auf die selbe `9` zeigt wie der Pfeil in `sol_y[0]`.
Das hat generell etwas mit dem Konzept von Referenzierung zu tun. Objekte werden halt viel öfter wiederverwendet als es manchem Anfänger bewusst ist. Bei veränderbaren Objekten wie Listen fällt es dann eher auf als z.B. bei Zahlen.drummer123 hat geschrieben: Dienstag 10. August 2021, 22:04 Ich finde zwar diese Verknüpfungen der Listen merkwürdig, aber so ist das eben...
-
- User
- Beiträge: 7
- Registriert: Dienstag 10. August 2021, 19:21
@_deets_ Gibt es eine Funktion, mit der man antworten kann, sodass man sieht, dass ich Ihnen antworte, aber dennoch nicht das Vollzitat eingeblendet
wird? Ich bin neu auf dem Forum und kenne noch nicht die ganzen Funktionen.
wird? Ich bin neu auf dem Forum und kenne noch nicht die ganzen Funktionen.
-
- User
- Beiträge: 7
- Registriert: Dienstag 10. August 2021, 19:21
Danke an alle Antworten.
Du kannst den quote bearbeiten, und zb nur einen Satz zitieren. Aber auch ein einfaches “@user” reicht. Das ist zwar dann nicht mit einer Benachrichtigung verknüpft, aber macht deine Antwort klar, und das ist das wichtige.