Can someone please explain this to me? This doesn\'t make any sense to me.
I copy a dictionary into another and edit the second and both are changed. Why is this hap
dict1
is a symbol that references an underlying dictionary object. Assigning dict1
to dict2
merely assigns the same reference. Changing a key's value via the dict2
symbol changes the underlying object, which also affects dict1
. This is confusing.
It is far easier to reason about immutable values than references, so make copies whenever possible:
person = {'name': 'Mary', 'age': 25}
one_year_later = {**person, 'age': 26} # does not mutate person dict
This is syntactically the same as:
one_year_later = dict(person, age=26)
In addition to the other provided solutions, you can use **
to integrate the dictionary into an empty dictionary, e.g.,
shallow_copy_of_other_dict = {**other_dict}
.
Now you will have a "shallow" copy of other_dict
.
Applied to your example:
>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = {**dict1}
>>> dict2
{'key1': 'value1', 'key2': 'value2'}
>>> dict2["key2"] = "WHY?!"
>>> dict1
{'key1': 'value1', 'key2': 'value2'}
>>>
Pointer: Difference between shallow and deep copys
>>> dict2 = dict1
# dict2 is bind to the same Dict object which binds to dict1, so if you modify dict2, you will modify the dict1
There are many ways to copy Dict object, I simply use
dict_1 = {
'a':1,
'b':2
}
dict_2 = {}
dict_2.update(dict_1)
When you assign dict2 = dict1
, you are not making a copy of dict1
, it results in dict2
being just another name for dict1
.
To copy the mutable types like dictionaries, use copy
/ deepcopy
of the copy module.
import copy
dict2 = copy.deepcopy(dict1)
On python 3.5+ there is an easier way to achieve a shallow copy by using the ** unpackaging operator. Defined by Pep 448.
>>>dict1 = {"key1": "value1", "key2": "value2"}
>>>dict2 = {**dict1}
>>>print(dict2)
{'key1': 'value1', 'key2': 'value2'}
>>>dict2["key2"] = "WHY?!"
>>>print(dict1)
{'key1': 'value1', 'key2': 'value2'}
>>>print(dict2)
{'key1': 'value1', 'key2': 'WHY?!'}
** unpackages the dictionary into a new dictionary that is then assigned to dict2.
We can also confirm that each dictionary has a distinct id.
>>>id(dict1)
178192816
>>>id(dict2)
178192600
If a deep copy is needed then copy.deepcopy() is still the way to go.
dict2 = dict1
does not copy the dictionary. It simply gives you the programmer a second way (dict2
) to refer to the same dictionary.