Shallow copy: why does the list change, but not the string?

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

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

Thus, the link to the list ['a', 'b', 'c'] is copied to y. Whenever I change the list (for example, x['key'].remove('a') ), both dict x and y change. I understand this part. But when I consider a situation like the one 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 has the same link. So my question is what makes a string different from a list? What is the mechanism of this?

+4
source share
2 answers

You do two different things. When you do

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

you mutate an object that refers to x['key'] . If another variable refers to the same object, you will also see a change from this point of view:

Pythontutor visualizationPythontutor visualization 2

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

PT vis 3

If you do

 y['user']='guest' 

you retype y['user'] on the new object. This, of course, does not affect x['user'] or the object it refers to.

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

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

you would not change y['key'] :

PT vis 4

Watch online at PythonTutor.com .

+14
source

The difference is that in one case you are assigning a new value to the dictionary key, while in the other case you are changing the existing value. Note the difference in the two parts of the code:

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

There is no = sign. You do not assign anything to the dictionary. In fact, the dictionary hardly even “knows” what is going on. You simply reach and manipulate the object inside the dictionary.

 y['user'] = 'guest' 

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

In the second case, you cannot make the remove equivalent because the strings are immutable. However, the difference is not "because the lines are immutable." The difference is that you mutate the list, 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 for the key at x , leaving y unaffected.

+5
source

Source: https://habr.com/ru/post/1493503/


All Articles