Search code examples
pythonpython-3.xcopy

When shallow copying a dictionary in Python, why is modifying a list value reflected in the original but a string value is not?


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.


Solution

  • 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.