Seite 1 von 1

dict.fromkeys verändert alle Elemente

Verfasst: Dienstag 19. Mai 2009, 21:09
von Thuught
Hallo,
ich hätte eine Frage zur Funktion fromkeys:

Code: Alles auswählen

alist=["a","b","c","d"]
d=dict.fromkeys(alist,{"foo":12})
for i in d.iteritems():print i
#=================================
# ('a', {'foo': 12})
# ('c', {'foo': 12})
# ('b', {'foo': 12})
# ('d', {'foo': 12})
#=================================
d["a"]["fuu"]=21
for i in d.iteritems():print i
#=================================
# ('a', {'foo': 12, 'fuu': 21})
# ('c', {'foo': 12, 'fuu': 21})
# ('b', {'foo': 12, 'fuu': 21})
# ('d', {'foo': 12, 'fuu': 21})
#=================================
Wieso unifiziert er alle Werte und wie kann ich das verhindern?

Verfasst: Dienstag 19. Mai 2009, 21:49
von b.esser-wisser
Probiers mit 'nem generator:

Code: Alles auswählen

>>> d = dict(( (c, {"foo":42}) for c in "abcd"))
>>> d["a"] is d["b"]
False
... Python kopiert Objekte nie automatisch, aber das fällt erst bei veränderbaren ('mutable') Objekten auf.

hth, Jörg

Verfasst: Dienstag 19. Mai 2009, 21:52
von EyDu
Es werden in Python keine Kopien implizit erstellt, sondern immer mit Referenzen gearbeitet. Wenn du eine Kopie möchtest, dann musst du diese explizit erzeugen.

In deinem Fall hast du also fünf Referenzen auf dein Dictionary. Da dieses mutable ist, werden Änderungen an jeder Referenz sichtbar, da diese immer noch das selbe Objekt referenzieren, nur dass dieses seinen Wert geändert hat.

Um das zu lösen musst du zu jeden Schlüssel einen neuen Wert erzeugen. Mach also einfach eine Schleife draus:

Code: Alles auswählen

>>> alist=["a","b","c","d"]
>>> d = {}
>>> for elem in alist:
	d[elem] = {"foo":12}

	
>>> d["a"]["bar"] = 42
>>> d["a"]
{'foo': 12, 'bar': 42}
>>> d["b"]
{'foo': 12}
Oder einen einfachen Generator.

Verfasst: Mittwoch 20. Mai 2009, 00:12
von Thuught
Das mit den Referenzen war mir nie so bewusst. Gut zu wissen.
Gibt es denn eine Möglichkeit bei Zuweisungen eine Kopie von Objekten zu erzwingen?

Verfasst: Mittwoch 20. Mai 2009, 00:39
von snafu
b.esser-wisser hat geschrieben:Python kopiert Objekte nie automatisch
Irgendwie fällt das momentan unter die Top-Aussagen im Forum. ;)

Verfasst: Mittwoch 20. Mai 2009, 07:37
von Leonidas
Thuught hat geschrieben:Gibt es denn eine Möglichkeit bei Zuweisungen eine Kopie von Objekten zu erzwingen?
Ja, indem du ``copy.copy`` nutzt.