Neues dict

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
wirrwarr
User
Beiträge: 2
Registriert: Montag 10. September 2012, 23:20

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!
Zuletzt geändert von Anonymous am Dienstag 11. September 2012, 06:30, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
anogayales
User
Beiträge: 456
Registriert: Mittwoch 15. April 2009, 14:11

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
wirrwarr
User
Beiträge: 2
Registriert: Montag 10. September 2012, 23:20

OK, vielen Dank!
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

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.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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... ;)
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

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 ;)
Antworten