dictionary1 = dictionary0, update dictionary1, dictionary0 == dictionary1 ?

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
hellmerf
User
Beiträge: 1
Registriert: Donnerstag 7. Januar 2021, 01:36

Hallo,
bei der Erstellung einer wx.listCtrl zum update eines dictionaries welches auf Knopfdruck wieder in seinen Initalzustand zurückgesetzt werden soll bin ich auf folgendes (für mich unverständliches) Verhalten gestossen:

dict0 = {'a': 1, 'b': 2}
dict1 = dict0
dict1.update({'b': 3})
print (dict1)
print (dict0)

{'a': 1, 'b': 3}
{'a': 1, 'b': 3}

Weshalb sind nach dem update eines dictionaries beide geändert ?

win10, Anaconda3, Spyder (python 3.8)
Lubuntu, Spyder (python 3.8)
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Weil = nur das gleiche Objekt an einen neuen Namen bindet. Du musst eine Kopie anlegen. Zb mit copy.deepcopy. Oder ggf reicht auch ein simples update.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast nur ein Wörterbuch, das an zwei unterschiedliche Namen gebunden wurde.
Wenn Du eine Kopie willst, mußt Du das Wörterbuch kopieren. Zum setzen eines Wertes nimmt man nicht update!

Code: Alles auswählen

initial_dictionary = {"a": 1, "b": 2}
working_dictionary = initial_dictionary.copy()
...
working_dictionary["b"] = 3
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Da Python mit Referenzen arbeitet, musst Du weiter beachten, ob die Inhalte in Deinen Dictionary mutable oder immutable sind. Für letzteres reicht das von Sirius3 genannte .copy, sonst brauchst Du ggf. das von __deets__ genannte copy.deepcopy.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1017
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Code: Alles auswählen

d0 = {'a': 1, 'b': 2}
d1 = d0

print(id(d0))
print(id(d1))
print(d0 is d1)

# 2441305636992
# 2441305636992
# True
# Bei dir kommt eine andere id
# aber d0 und d1 sind ein und das selbe Objekt
Das ist mit allen veränderlichen Container und Sequenzen so.
Wenn d1 von d0 eine Kopie sein soll:

Code: Alles auswählen

d0 = {'a': 1, 'b': 2}
d1 = d0.copy()
Aber Vorsicht, wenn man verschachtelt, geht das nicht.

Code: Alles auswählen

seq = [1, 2, 3]
d0 = {"a": seq}

d1 = d0.copy()

seq[0] = 42

print(seq)
print(d1)
[42, 2, 3]
{'a': [42, 2, 3]}
Ist auch ein gelöstes Problem:

Code: Alles auswählen

import copy


seq = [1, 2, 3]
d0 = {"a": seq}

d1 = copy.deepcopy(d0)

seq[0] = 42

print(seq)
print(d1)
[42, 2, 3]
{'a': [1, 2, 3]}
Die Liste ist mittels copy.deepcopy auch kopiert worden. copy.copy macht nur flache Kopien.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten