Seite 1 von 1

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

Verfasst: Donnerstag 7. Januar 2021, 02:05
von hellmerf
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)

Re: dictionary1 = dictionary0, update dictionary1, dictionary0 == dictionary1 ?

Verfasst: Donnerstag 7. Januar 2021, 09:42
von __deets__
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.

Re: dictionary1 = dictionary0, update dictionary1, dictionary0 == dictionary1 ?

Verfasst: Donnerstag 7. Januar 2021, 09:55
von Sirius3
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

Re: dictionary1 = dictionary0, update dictionary1, dictionary0 == dictionary1 ?

Verfasst: Donnerstag 7. Januar 2021, 10:27
von kbr
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.

Re: dictionary1 = dictionary0, update dictionary1, dictionary0 == dictionary1 ?

Verfasst: Freitag 8. Januar 2021, 14:29
von DeaD_EyE

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.