Search code examples
pythonshallow-copy

Shallow copy: why is list changing but not a string?


I understand that when you do a shallow copy of a dictionary, you actually make a copy of the references. So if I do this:

x={'key':['a','b','c']}
y=x.copy()

So the reference of the list ['a','b','c'] is copied into y. Whenever I change the list ( x['key'].remove('a') for example), both dict x and y will change. This part I understand. But when I consider situation like this below:

x={'user':'admin','key':['a','b','c']}
y=x.copy()

When I do y['user']='guest', x['user'] will not change, but the list still shares the same reference. So my question is what makes the string different than the list? What is the mechanism behind this?


Solution

  • You're doing two different things. When you do

    x['key'].remove('a')
    

    you mutate the object that x['key'] references. If another variable references the same object, you'll see the change from that point of view, too:

    Pythontutor visualization Pythontutor visualization 2

    However, in the second case, the situation is different:

    PT vis 3

    If you do

    y['user']='guest'
    

    you rebind y['user'] to a new object. This of course does not affect x['user'] or the object it references.

    This has nothing to do with mutable vs. immutable objects, by the way. If you did

    x['key'] = [1,2,3]
    

    you wouldn't change y['key'] either:

    PT vis 4

    See it interactively on PythonTutor.com.