Zuweisung von Listenelementen in eine andere 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
Khris
User
Beiträge: 13
Registriert: Dienstag 17. Mai 2011, 11:33

Hallo zusammen,

ich bin noch ziemlicher Anfänger in Python (habe vorher in Fortran programmiert) und habe jetzt im Zuge einer Fehlersuche mal testweise folgendes ausprobiert:

Ich habe mit zwei Listen wie folgt definiert (ich nutze hier ipyhon unter Linux):

Code: Alles auswählen

In [15]: b
Out[15]: [[0, 0], [0, 0]]

In [16]: a
Out[16]: [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]
Und als nächstes folgendes gemacht:

Code: Alles auswählen

In [18]: b[0][0]=a[0][0][0]
Gestern bekam ich folgendes unverständliches Ergebnis:

Code: Alles auswählen

In [19]: b
Out[19]: [[1, 0], [1, 0]]
Heute probierte ich dasselbe und bekam das hier:

Code: Alles auswählen

In [6]: b
Out[6]: [[1, 0], [0, 0]]
Was geht da vor? Hat mein Python ne Meise oder ist diese Operation einfach falsch und sollte so nicht ausgeführt werden, weil sie zu einem zufälligen Ergebnis führt?
Und wenn ja, wie kann ich Elemente einer Liste direkt einer anderen Liste zuordnen ohne append oder extend zu benutzen?

Ganz konkret will ich folgendes machen, weiß aber nicht, ob es funktioniert mit Listen, ich übernehme die Methode aus Fortran:

Code: Alles auswählen

for i in range(x):
   for j in range(y):
       b[i][j]=a[i][j][0]
In Tutorials findet man zu Listen leider immer nur simple eindimensionale Beispiele, ich arbeite aber mit Listen die teils tausende Einträge und mehrere Dimensionen haben, daher sind zu solchen Fällen oft kaum Beispiele zu finden.

Vielen Dank für die Hilfe schon mal.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wie hast Du b erzeugt? Probiere mal folgendes:

Code: Alles auswählen

b[0] is b[1]
Wenn da `True` rauskommt, so sind die beiden Listen in `b` identisch! Das erklärt das Problem bei der ersten Zuweisung.

Generell musst Du aufpassen, dass in Python beim Binden an Namen die Objekte nicht kopiert werden, sondern ein und dasselbe Objekt an verschiedene Namen gebunden sein kann:

Code: Alles auswählen

In [3]: a = [1, 2, 3]

In [4]: b = a

In [5]: a is b
Out[5]: True

In [6]: b.append("foo")

In [7]: b
Out[7]: [1, 2, 3, 'foo']

In [8]: a
Out[8]: [1, 2, 3, 'foo']
`a` ist an dasselbe Listenobjekt gebunden wie b. Ändere ich das Objekt über den Namen `b`, so erhalte ich beim Zugriff über den Namen `a` dasselbe Objekt.

Will man eine Kopie des Objektes, so kann man das copy-Modul nutzen:

Code: Alles auswählen

In [9]: from copy import copy

In [10]: c = copy(b)

In [11]: c.append("bar")

In [12]: c
Out[12]: [1, 2, 3, 'foo', 'bar']

In [13]: b
Out[13]: [1, 2, 3, 'foo']

In [14]: c is b
Out[14]: False
Für tiefere Strukturen gibt es auch noch `deepcopy`.

Für derartige Fälle solltest Du Dir aber definitiv mal `numpy` angucken. Das ist für Matrizen-Operationen geeigneter, als simple Python-Listen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Khris: Wie ist denn `b` gestern und heute entstanden? Da liegt nämlich der Unterschied:

Code: Alles auswählen

In [142]: b = [[0, 0], [0, 0]]

In [143]: b[0][0] = 1

In [144]: b
Out[144]: [[1, 0], [0, 0]]

In [145]: a = [0, 0]

In [146]: b = [a, a]

In [147]: b
Out[147]: [[0, 0], [0, 0]]

In [148]: b[0][0] = 1

In [149]: b
Out[149]: [[1, 0], [1, 0]]
Im ersten Fall enthält `b` zwei verschiedene Listen und im zweiten Fall zweimal die *selbe* Liste. Und wenn man die verändert, nun ja dann verändert man die halt. In Python werden nie implizit Kopien von Objekten erzeugt. Bei Zuweisungen wird immer nur mit Verweisen auf Objekten gearbeitet.

Wenn das so Fortran-typischer numerischer Kram mit mehrdimensionalen Arrays ist, dann solltest Du `numpy` vielleicht ins Auge fassen, statt das 1:1 in Python mit Listen zu übersetzen.
Khris
User
Beiträge: 13
Registriert: Dienstag 17. Mai 2011, 11:33

Leider erinnere ich mich nicht mehr genau, wie ich b gestern erzeugt habe, aber die Erklärung ist einleuchtend, danke!

Und diese for-Schleife habe ich dann auch mit Hilfe von numpy-Arrays realisieren können, da funktioniert das alles.
Ich muss mich nur noch an die Eigenschaften von Listen und all das gewöhnen. :D
Antworten