Seite 1 von 1

Dictionaries, Listen, warum passiert folgendes ?

Verfasst: Montag 23. April 2007, 15:11
von rolgal_reloaded
Hallo zusammen,

jetzt war ich doch etwas überrascht.

Code: Alles auswählen

>>> dictionary = {1:["eins", "zwei", "drei"],2:["zwei","drei","vier"]}
>>> listen = dictionary.values()
>>> for liste in listen:
	liste.append("\n")

	
>>> listen
[['eins', 'zwei', 'drei', '\n'], ['zwei', 'drei', 'vier', '\n']]
>>> dictionary
{1: ['eins', 'zwei', 'drei', '\n'], 2: ['zwei', 'drei', 'vier', '\n']}
>>> 
Ich verstehe nicht, warum die Listen im Dictionary auch verändert werden?
Mit listen = dictionary.values() wird doch ein Objekt des Typs list erzeugt.
Und nur dieses - also die eigentlich die Listen innerhalb - wollte ich verändern.

LG

rolgal_reloaded[/code]

Verfasst: Montag 23. April 2007, 15:13
von mitsuhiko
.values() / .itervalues() erzeugt einfach nur eine liste bzw einen Iterator mit Referenzen auf die Objekte im Dict. Es erzeugt natürlich keine Kopien, das wäre sehr langsam.

Um eine Kopie einer Liste zu erstellen kannst du copy.copy(deineliste) verwenden oder einfach nur deineliste[:].

Verfasst: Montag 23. April 2007, 16:30
von rolgal_reloaded
HI blackbird,

danke, das erklärt einiges.

Hat Python das schon immer so gemacht oder ist das erst mit einer bestimmten Version gekommen?

LG

rolgal_reloaded

Verfasst: Montag 23. April 2007, 16:53
von CM
Hoi,

ohne Garantie: Das hat Python schon immer so gemacht.

Weshalb ich schreibe: Man übersieht je nach Code leicht, daß copy.copy() nicht ausreichend ist und ist dann ewig auf der Suche nach dem Bug. Deshalb bin ich jetzt angefange .copy() durch copy.deepcopy() zu ersetzen.

Gruß,
Christian

Verfasst: Montag 23. April 2007, 17:04
von birkenfeld
Wenn man ständig deepcopy() verwendet, macht man irgendwas falsch.

copy.deepcopy() brauche ich fast nie, wenn dann höchstens dict.copy() oder list[:].

Verfasst: Montag 23. April 2007, 17:29
von rolgal_reloaded
@cm, birkenfeld

Habt ihr da kleine Beispiele wann ihr das eine oder andere wie verwendet?

Liebe Grüße

rolgal_reloaded

Verfasst: Montag 23. April 2007, 19:59
von Zap
Ich hab mich bestimmt schon schon 2-3 mal dabei erwischt das ich
bei 'list' genauso wie 'dict' eine methode copy() verwendeten wollte.
Wurde dann immer vom Interpreter zurück gepfiffen :?

Gibt es eigentlich nen Grund das es kein list().copy() gibt ?
Oder ist das nur nicht implementiert worden da es bereits list()[:] gab?
(Was ich übrigens erst seit heute kenne ;) )
Benutzte bisher auch immer copy.copy()

Verfasst: Montag 23. April 2007, 20:55
von BlackJack
Warum sollte man den einzelnen Objekten eine Methode verpassen, für die es eine generische Funktion `copy.copy()` gibt? Wobei ich bei Listen immer den "Konstruktor" benutze, also ``neue_liste = list(alte_liste)``.

Verfasst: Montag 23. April 2007, 21:41
von Zap
Tja, warum sollte man das tun ?!?
Nur komisch bei dict wurde es getan ;)

Verfasst: Donnerstag 3. Mai 2007, 15:19
von CM
Hoi,

sorry, ich war eine Weile offline - und an dem Tag dieses letzten Posts hier definitv nicht auf der Höhe. Danke, birkenfeld, daß Du das gerade gerückt hast.

Also, deepcopy verwendet ich tatsächlich nur, um eine tiefe Kopie von "compound" Objekten zu machen. Beispiel:

Code: Alles auswählen

# instanzieren eines Objektes und füttern mit Daten (hier bewußt getrennt)
x = SAXSdata().from_asa(path)
# anschließende tiefe Kopie in eine Liste (hier: datasets) 
datasets.append(copy.deepcopy(x))
# auf das x kann man natürlich verzichten
An dieser Stelle ich deepcopy notwendig, weil SAXSdata() ein compound" Objekt ist, d. h. ein Objekt, daß andere Objekte (hier einen Haufen numpy arrays) enthält. Eine tiefe Kopie inseriert hier nur *Kopien* der anderen Objekte in die Kopie des "Masterobjektes" anstelle derselben *Objekte*, wie sie im "Masterobjekt" enthalten sind. Ansonsten kann es dazu führen, daß in einem Namespace nicht das "neue" x, sondern der Inhalt der in einem älteren "x" enthaltenen Objekte an "datasets" gehangen werden.

M.a.W. deepcopy hat zwar seine Berechtigung, aber mein erster Post hier war Blödsinn! Tut mir leid.

Gruß,
Christian

Verfasst: Donnerstag 3. Mai 2007, 16:07
von birkenfeld
Zap hat geschrieben:Tja, warum sollte man das tun ?!?
Nur komisch bei dict wurde es getan ;)
Vielleicht weil das copy-Modul neuer ist als die copy-Methode von Dicts?

Verfasst: Donnerstag 3. Mai 2007, 19:10
von Joghurt
rolgal_reloaded hat geschrieben:Hat Python das schon immer so gemacht oder ist das erst mit einer bestimmten Version gekommen?
Das hat Python schon immer so gemacht, hängt mit der Grundphilosophie "Alles ist eine Referenz" zusammen.