質問

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?

役に立ちましたか?

解決

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.

他のヒント

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top