为什么当我执行以下操作时:
x = y = {}
每次修改时,x都像x[1] = 5
一样,我也最终修改了y,反之亦然?
答案 0 :(得分:7)
您将名称x
和y
分配为指向同一个字典,您会期望什么行为?
如果您希望他们指向不同的词典,请使用
x = {}
y = {}
或
x,y = {},{}
答案 1 :(得分:2)
因为x和y引用相同的字典。
引擎盖下发生了什么:
----- -------
| x | = | ref |-----
----- ------- |
v
------
| {} |
------
^
----- ------- |
| y | = | ref |-----
----- -------
阅读可变和不可变数据:
答案 2 :(得分:1)
这就是引用的工作原理。对于x = y = {}
,有两个引用变量,但它们都指向同一个对象。使用x[1] = 5
,您实际上并不是在修改x
本身,而是修改x
引用的对象。这与y
引用的对象相同,除非您将x
和/或y
设置为引用新对象。
答案 3 :(得分:1)
Python上的变量不像“盒子”(你放置对象的地方)那样工作,而是像“标签”(你给对象分配名字)。
所以当你这样做时:
x = y = {}
你真的对Python说:
我想将 {} 称为 x 和 y 。
理解这一点的另一种方法是 {} 语法只是 dict()的快捷方式,它只返回一个新的 Dict 宾语。所以另一种看法是:
x = y = dict()
这只返回一个 dict对象,并为其指定两个名称( x 和 y )。
答案 4 :(得分:0)
正如其他答案所说,原来的问题发生了,因为你正在分配一个参考。下一个混乱的程度是当你做这样的事情时:
a = [[1]]
b = a[:] # You might think [:] will protect you from the original gotcha.
a[0][0] = 2
print b[0][0] # It's 2...why did this change?
它发生了变化,因为a [:]切片实际上正在复制对[0]的引用。换句话说,即使a和b引用不同的列表,因为你使用了[:],每个列表中的第一个元素都指向同一个列表。这是新形式的原始问题。这里的正确方法是
import copy
a = [[1]]
b = copy.deepcopy(a)
a[0][0] = 2
print b[0][0] # 1