Why does this empty dict break shared references?

风格不统一 提交于 2019-12-11 03:23:29

问题


I have found some Python behavior that confuses me.

>>> A = {1:1}
>>> B = A
>>> A[2] = 2
>>> A
{1: 1, 2: 2}
>>> B
{1: 1, 2: 2}

So far, everything is behaving as expected. A and B both reference the same, mutable, dictionary and altering one alters the other.

>>> A = {}
>>> A
{}           # As expected
>>> B
{1: 1, 2: 2} # Why is this not an empty dict?

Why do A and B no longer reference the same object?

I have seen this question: Python empty dict not being passed by reference? and it verifies this behavior, but the answers explain how to fix the provided script not why this behavior occurs.


回答1:


Here is a pictorial representation *:

A = {1: 1} 
# A -> {1: 1}
B = A
# A -> {1: 1} <- B
A[2] = 2
# A -> {1: 1, 2: 2} <- B
A = {}
# {1: 1, 2: 2} <- B    
# A -> {}

A = {} creates a completely new object and reassigns the identifier A to it, but does not affect B or the dictionary A previously referenced. You should read this article, it covers this sort of thing pretty well.


Note that, as an alternative, you can use the dict.clear method to empty the dictionary in-place:

>>> A = {1: 1}
>>> B = A
>>> A[2] = 2
>>> A.clear()
>>> B
{}

As A and B are still references to the same object, both now "see" the empty version.


* To a first approximation - similar referencing behaviour is going on within the dictionary too, but as the values are immutable it's less relevant.




回答2:


Remember, variables in python act like labels. So, in the first example, you have a dictionary {1: 1, 2: 2}. That dictionary stays in memory. In the first example, A points to that dictionary, and you say B points to what A is pointing to (It won't point to the label A, but rather what the label A is pointing to).

In the second example, A and B are both pointing to this dictionary, but you point A to a new dictionary ({}). B stays pointing to the old dictionary in memory from the first example.




回答3:


you are changing the dictionary A points to when you say A={} not destroying the old dictionary ... this sample should demonstrate for you

A={1:1} 
print id(A)
B = A
print id(B)
B[2] = 5
print id(B)
print A
print id(A)
A = {}
print id(A)



回答4:


It's about the difference between creating a new dictionary and changing an existing dictionary.

A[2] = 2

Is modifying the dictionary by adding a new key, the existing stuff is still part of that dictionary.

A = {}

This creates a totally new empty dictionary.




回答5:


Think about it like this: A is the name of one object, then you make B a different name for that object. That's the first part, but then in the second code you make a new object and say ok that old object isn't called A anymore now this new object is called A.

B isn't pointing at A. B and A are both names for the same object, then names for two different objects.



来源:https://stackoverflow.com/questions/29952200/why-does-this-empty-dict-break-shared-references

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!