Frage

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?

War es hilfreich?

Lösung

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.

Andere Tipps

The difference is that in once case, you are assigning a new value to the dictionary key, whereas in the other case, you are modifying the existing value. Notice the difference in your two pieces of code:

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

There is no = sign here. You are not assigning anything in the dictionary. In fact, the dictionary hardly even "knows" what's going on. You're just reaching in and manipulating an object inside the dictionary.

y['user'] = 'guest'

Here you are actually assigning a new value to the dictionary key.

You cannot do the equivalent of remove in the second case because strings are immutable. However, the difference is not "because strings are immutable". The difference is that you are mutating the list and not the string. You can get the behavior of the second example in the first case by doing

x['key'] = ['new', 'list']

This will assign a new value to the key in x, leaving y unaffected.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top