Seite 1 von 1

Neues dict

Verfasst: Montag 10. September 2012, 23:27
von wirrwarr
Guten Tag,

mich würde interessieren warum verhält sich der unten stehende Code in dieser Art und Weise?
Müsste nicht für jeden funktionsaufruf ein eigenständiges dict-objekt erzeugt werden? Was habe ich da falsch verstanden?

Code: Alles auswählen

a = {"k1": []}

def x():
    b = dict(a)
    b["k1"].append("V")
    print id(b)
    print b

x()
x()
x()
print "-"*79
print "A = ", A

"""
Output:
163141396
{'k1': ['V']}
161615492
{'k1': ['V', 'V']}
161614404
{'k1': ['V', 'V', 'V']}
-------------------------------------------------------------------------------
A =  {'k1': ['V', 'V', 'V']}
"""
Vielen Dank für eure Hilfe!

Re: Neues dict

Verfasst: Montag 10. September 2012, 23:34
von anogayales
Das liegt daran, dass in der ersten Zeile eine Liste erstell wird, die du immer wieder weiter verwendest. Sprich, in "a" wird unter dem Key "k1" eine Referenz zu einer Liste gespeichert. Mit b = dict(a) wird keine Kopie des kompletten dictionaries erstellt. Sprich, die Referenz wird dadurch nicht geändert.

Wenn du willst, dass die Liste am Anfang leer ist, pack einfach "a = {"k1": []}" in die Funktion. Wenn du mit komplexeren Objekten zu tun hast, wäre ein http://docs.python.org/library/copy.html vielleicht ganz hilfreich.

Grüße,
anogayales

Re: Neues dict

Verfasst: Montag 10. September 2012, 23:39
von wirrwarr
OK, vielen Dank!

Re: Neues dict

Verfasst: Dienstag 11. September 2012, 07:23
von sparrow
Das "Problem" ist, dass du das Dictionary "a" auf Modulebene erstellst, also nicht innerhalb einer Funktion. Willst du dann innerhalb einer Funktion darauf zugreifen, sucht er erst lokal (im Namensraum der Funktion) und anschließend auf Modulebene, falls er nicht fündug geworden ist.

Variablen auf Modulebene sind nur in ganz, ganz wenigen Fällen sinnvoll. In der Regel weisen sie auf ein falsches - oder unsauberes - Vorgehen hin.

Re: Neues dict

Verfasst: Dienstag 11. September 2012, 08:31
von snafu
sparrow hat geschrieben:Das "Problem" ist, dass du das Dictionary "a" auf Modulebene erstellst, also nicht innerhalb einer Funktion. Willst du dann innerhalb einer Funktion darauf zugreifen, sucht er erst lokal (im Namensraum der Funktion) und anschließend auf Modulebene, falls er nicht fündug geworden ist.
Das hat nichts damit zu tun, ob ein Dictionary auf Modulebene erzeugt wurde oder nicht (außer ich habe dich falsch verstanden), sondern damit - wie schon angeprochen wurde - dass bei Übergabe eines anderen Wörterbuchs an den Konstruktor eines neuen `dict`-Objekts die Werte unverändert übernommen werden. Bei `b = dict(a)` verwendet `b` also exakt die Liste, die in `a` steckt. Wird dann ein neues Element an die Liste in `b` gehangen, so steckt dieses neue Element folglich auch in der Liste von `a` - eben weil alles *ein* Objekt ist. Wiederholte Aufrufe der Funktion verwenden weiterhin jeweils `a`, dessen Liste sich durch das Anfügen über `b` stetig verändert. Auch wenn `b` selbst (als `dict`-Instanz) natürlich ein jeweils neues Objekt mit eigener ID ist. Hätte man übrigens durch simples Nachlesen in der Doku eigentlich auch ohne Forum erfahren können... ;)

Re: Neues dict

Verfasst: Dienstag 11. September 2012, 09:39
von sparrow
Ja schon, aber das vom OP erfragte Verhalten würde dann auftauchen, wenn man das dict erst in der Funktion definiert. Daher bin ich davon ausgegangen, dass das die Wurzel allen Übels ist ;)