Seltsames Verhalten einer 2-dimensionalen Liste

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
KlausMerkert
User
Beiträge: 22
Registriert: Freitag 22. Mai 2009, 11:16

Liebe Python-Fachleute,

ich bin auf ein seltsames Verhalten einer Liste gestoßen, das ich mir nicht erklären kann. Je nachdem wie ich die Liste erzeuge, ergibt sich später bei der Änderung eines Elementes, dass mehrere Elemente geändert werden oder nur das eine. Es scheint so zu sein, dass ein dynamisches Erzeugen der Liste (siehe f1) den Fehler provoziert. Erstelle ich die Liste direkt (siehe f), so bleibt der Fehler aus. Ich bin schon etwas verwirrt, zumal Python die beiden Listen für gleich hält. Kann mir jemand einen Tipp geben? Gerne lese ich auch irgendetwas nach, wenn ich weiß, wo.

Viele Grüße

Klaus Merkert

Code: Alles auswählen

zeile = [6,6,6,6]                   # nicht ok
f1 = []
for i in range(3):
    # f.append(zeile) 
    f1 = f1 + [zeile]

f = [[6,6,6,6],[6,6,6,6],[6,6,6,6]] # ok

"""
f = []                              # ok
for i in range(3):
    f = f + [[6,6,6,6]]
"""
"""
f = [[6]*4]*3                       # nicht ok
"""
"""
zeile = list(((6,)*4))              # nicht ok
f = []                              
for i in range(3):
    f = f + [zeile]
"""
print('f==f1?',f==f1)
print('mit f1 nicht ok')
print(f1)
f1[0][2] = 1
print(f1)
print('mit f ok')
print(f)
f[0][2] = 1
print(f)
ergibt die Ausgabe

Code: Alles auswählen

>>> 
f==f1? True
mit f1 nicht ok
[[6, 6, 6, 6], [6, 6, 6, 6], [6, 6, 6, 6]]
[[6, 6, 1, 6], [6, 6, 1, 6], [6, 6, 1, 6]]
mit f ok
[[6, 6, 6, 6], [6, 6, 6, 6], [6, 6, 6, 6]]
[[6, 6, 1, 6], [6, 6, 6, 6], [6, 6, 6, 6]]
>>> 
Benutzeravatar
lutz.horn
User
Beiträge: 205
Registriert: Dienstag 8. November 2005, 12:57
Wohnort: Pforzheim

Egal wie oft Du 'zeile' verwendest, es handelt sich immer um die selbe Liste. Wenn Du eines ihrer Elemente änderst, wird diese Änderung auch überall sonst, wo auf sie verwiesen wird, sichtbar.
https://www.xing.com/go/invite/18513630.6a91d4
Panke
User
Beiträge: 185
Registriert: Sonntag 18. März 2007, 19:26

So wie Du die Liste per Schleife erstellst, ist in der Ergebnisliste eine einzige Liste dreifach
enthalten.

Code: Alles auswählen

zeile = [6,6,6,6]                   # nicht ok
f1 = []
for i in range(3):
    # f.append(zeile) 
    f1 = f1 + [zeile]

print f1[0] is f1[1]
KlausMerkert
User
Beiträge: 22
Registriert: Freitag 22. Mai 2009, 11:16

Lieber Lutz Horn,

vielen Dank für den Hinweis, darauf hätte ich eigentlich kommen müssen.
So funktioniert es:

Code: Alles auswählen

zeile = [6,6,6,6]                   
f = []
for i in range(3):
    f.append(zeile[:])    

print(f)
f[0][2] = 1
print(f)
Viele Grüße

Klaus Merkert
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

KlausMerkert hat geschrieben:Ich bin schon etwas verwirrt, zumal Python die beiden Listen für gleich hält.
Es waere etwas schwierig, wenn gleiche Listen nicht gleich waeren. Du solltest dich - wie lutz.horn und Panke schon angedeutet haben - mit dem Unterschied von Identitaet, zwei Objekte sind ein und dasselbe Objekt, und Gleichheit, zwei Objekte enthalten die gleichen Informationen, vertraut machen.

List Comprehensions sind hier sehr nuetzlich:

Code: Alles auswählen

two_dim = [[6,6,6] for _ in xrange(3)]
KlausMerkert
User
Beiträge: 22
Registriert: Freitag 22. Mai 2009, 11:16

Vielen Dank cofi für den guten Tipp.

Viele Grüße

Klaus Merkert
Antworten