Dictionaries, Listen, warum passiert folgendes ?

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
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

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]
Zuletzt geändert von rolgal_reloaded am Montag 23. April 2007, 16:29, insgesamt 1-mal geändert.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

.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[:].
TUFKAB – the user formerly known as blackbird
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

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
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Wenn man ständig deepcopy() verwendet, macht man irgendwas falsch.

copy.deepcopy() brauche ich fast nie, wenn dann höchstens dict.copy() oder list[:].
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

@cm, birkenfeld

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

Liebe Grüße

rolgal_reloaded
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

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()
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)``.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Tja, warum sollte man das tun ?!?
Nur komisch bei dict wurde es getan ;)
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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?
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

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.
Antworten