dictionaries automatisch (hokospokus) überschrieben

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
KorFreier
User
Beiträge: 8
Registriert: Freitag 16. Januar 2009, 17:14
Wohnort: Hamburg

Dienstag 28. April 2009, 11:46

Hallo Leute,

ich hab ein Phänomen, aus dem ich nicht schlau werde und würde mich sehr über eine Erklärung freuen (weil es mir ziemlich mystisch bis unlogisch erscheint):

Ich hab mehrere Dictionaries, mehrdimensional, alle gleich und am Beginn ohne values hinter allen Keys (die sollten separat in Schleifen eingetragen werden).

Jetzt fülle ich eines dieser Dicts mittels einer Schleife auf (in meinem Fall das agpm_out) und ...
- plop - haben alle gleichartigen Dicts die gleiche Füllung , obwohl die "="-Zuweisung oberhalb der Schleife ist???. So hat zum Beispiel das Dict opt_out auch eine Füllung nachdem man die Schleife ausführt.

Der Code sieht so aus:

Code: Alles auswählen

key1 = pinput.keys()
key2 = pinput[key1[0]].keys()
key3 = pinput[key1[0]][key2[0]].keys()
years = pinput[key1[0]][key2[0]][key3[0]].keys()
parameters = pinput[key1[0]][key2[0]][key3[0]][years[0]].keys()

## ------- erstellen des virgin-dictionaries
agpm_out  = {}
agpm_out_wet = {}
agpm_out_dry = {}
agpm_out_nor = {}

for dens in key1:
    opt_out = {}
    for opt in key2:
        ens_out = {}
        for ens in key3:
            year_out = {}
            for year in years:
                para_out = {}
                for para in parameters:
                    para_out[para] = {}
                para_out['agpm_bef'] = {}  # AGPM_BEF is the agpm_end of the year before
                year_out[year]=para_out
            ens_out[ens]= year_out
        opt_out[opt] = ens_out
    agpm_out[dens] = opt_out
agpm_out_wet = agpm_out
agpm_out_dry = agpm_out
agpm_out_nor = agpm_out

## -------- zuordnen der Parameter in das dictionary agpm_out
for dens in key1:
    for opt in key2:
        for ens in key3:
            for year in years[1:]: # funktioniert erst ab dem zweiten jahr, da endwert des vorjahres existieren muss
                for para in parameters:
                    agpm_out[dens][opt][ens][year][para] = pinput[dens][opt][ens][year][para]
                agpm_out[dens][opt][ens][year]['agpm_bef'] = pinput[dens][opt][ens][year-1]['agpm_end']
                # hier wird vorjahreswert zugeordnet
Hinzufügen von...

Code: Alles auswählen

 agpm_out = {}
ändert nichts an dem Phänomen. agpm_out ist dann wieder leer, aber die Geschwisterchen bleiben "schwanger".

Hat jemand eine Idee, um welchen Fehler (ich vermute mal Denkfehler meinerseits :oops: ) handeln könnte? Wäre sehr dankbar...
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Dienstag 28. April 2009, 12:04

Jetzt schreibe 100 mal an die Tafel: "ein '=' macht keine Kopie"! :wink:
Nach

Code: Alles auswählen

agpm_out_wet = agpm_out
agpm_out_dry = agpm_out
agpm_out_nor = agpm_out
sind "agpm_out_wet", "agpm_out_dry", "agpm_out_nor" drei Namen für dasselbe Object (!) - copy.copy(), copy.deepcopy() könnten weiterhelfen.

hth, Jörg
KorFreier
User
Beiträge: 8
Registriert: Freitag 16. Januar 2009, 17:14
Wohnort: Hamburg

Dienstag 28. April 2009, 12:40

Vielen Dank für die Antwort,
copy.deepcopy(agpm_out) funktioniert wie gewünscht. :D

Mit der "Strafaufgabe" hab ich daher kein Problem :roll: , aber...

um auszuschließen, dass ein Objekt nur verschiedene Namen trägt, hab ich den "agpm_out = {} - Test" gemacht.

Wenn also alle Objekte darauf reagieren, was ich mit agpm_out mache, warum sind sie dann am Ende nicht leer?

Sprich: Nach welchen Gesetzen läuft das, dass ein "=" verschiedene Sachen machen kann (zuweisen, Objekte gleichsetzen)?

(deine Antwort schreib ich dann auch noch hundert mal dazu, dann haben wir wenigstens einen anständigen Lerneffekt) :wink:
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Dienstag 28. April 2009, 12:52

KorFreier hat geschrieben:"agpm_out = {} - Test" gemacht
Weil du damit nicht das Dict aenderst, auf das agpm_out zeigt, sondern agom_out auf ein neues (leeres) Dict zeigen laesst, waehrend deine anderen Namen noch auf das urspruengliche Dict zeigen.

Wenn du wissen willst, ob du es mit gleichen Objekten zu tun hast, kannst du sie mit is vergleichen oder auch mal id() auf sie anwenden.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
KorFreier
User
Beiträge: 8
Registriert: Freitag 16. Januar 2009, 17:14
Wohnort: Hamburg

Dienstag 28. April 2009, 13:10

:idea:

Jetzt haben wir dann eine exponentielle Lernkurve. Hab's geschnallt, Dank zusammen.

Code: Alles auswählen

agpm_out is agpm_out_dry


...stellt alles klar und ist ohnehin (und überhaupt) ein Befehl, den ich schon lange benutzen hätte können (um zum Beispiel zu testen, ob neue, schnelle Prgrämmchen immer noch das gleiche Ergebnis erzielen, wie die alten, langsamen).

:)

Vielen Dank zusammen!
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dienstag 28. April 2009, 13:15

KorFreier hat geschrieben:

Code: Alles auswählen

agpm_out is agpm_out_dry


...stellt alles klar und ist ohnehin (und überhaupt) ein Befehl, den ich schon lange benutzen hätte können (um zum Beispiel zu testen, ob neue, schnelle Prgrämmchen immer noch das gleiche Ergebnis erzielen, wie die alten, langsamen)]
"is" überprüft aber nur, ob es sich um das _selbe_ (im Sinn von "an der selben Speicherstelle") Objekt handelt, es prüft nicht auf Gleichheit. Wenn du ein altes und ein neues Ergebnis vergleichen willst, dann musst du "==" benutzen.
Das Leben ist wie ein Tennisball.
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Dienstag 28. April 2009, 13:18

Du solltest auf jeden Fall mal [wiki=Objekte]in's Wiki [/wiki] schauen, der Artikel (bzw. effbots Original ) sind ein absolutes Muss für jeden Python-Quereinsteiger
KorFreier
User
Beiträge: 8
Registriert: Freitag 16. Januar 2009, 17:14
Wohnort: Hamburg

Dienstag 28. April 2009, 14:23

Gute Lektüre: Ich hab mir schon so was gedacht, als das Wort "zeigen" erwähnt wurde.

Ab sofort denk ich nur noch in Objekten... :wink:
DasIch
User
Beiträge: 2479
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Dienstag 28. April 2009, 14:26

Dennda hat da mal einen netten Blogpost zu gemacht.
Antworten