Python变量赋值混乱

时间:2010-07-12 21:22:34

标签: python

为什么当我执行以下操作时:

x = y = {}

每次修改时,x都像x[1] = 5一样,我也最终修改了y,反之亦然?

5 个答案:

答案 0 :(得分:7)

您将名称xy分配为指向同一个字典,您会期望什么行为?

如果您希望他们指向不同的词典,请使用

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