My understanding is that using .copy()
creates a shallow copy of a dictionary, so when you modify the copy, it will be reflected in the original (since it is a reference). When the dictionary value is a list, this is indeed the case. However, when the value is a string, the change is not reflected in the original. Example:
In [36]: x = {"string": "example", "list": []}
In [37]: y = x.copy()
In [38]: x
Out[38]: {'string': 'example', 'list': []}
In [39]: y
Out[39]: {'string': 'example', 'list': []}
In [40]: y["string"] += " one"
In [41]: x
Out[41]: {'string': 'example', 'list': []}
In [42]: y
Out[42]: {'string': 'example one', 'list': []}
In [43]: y["list"].append("one")
In [44]: x
Out[44]: {'string': 'example', 'list': ['one']}
In [45]: y
Out[45]: {'string': 'example one', 'list': ['one']}
Why does this behavior change based on the value of the key? I'm aware that copy.deepcopy
should be used for modification after copying, but I'm very confused by this behavior.
The behavior doesn't change on based on the value in the dict. You are doing two completely different things so the result you are seeing is different.
In the list
case, you are mutating the list. In the str
case, you are not mutating the string. If you did the same thing with the list:
y["list"] = y["list"] + ["one"]
You would see the same behavior.