为什么集合的增强赋值行为不同?

3

我正在使用普通的集合并运算,有两种方式,即x|=set([4,5,6])x=x|set([4,5,6]),为什么它们会表现不同呢?

对于简单的整数变量,它的工作方式是相同的,即无论我使用x=x+1还是x+=1,结果都是相同的。

x=set([1,2,3])
y=x
x|=set([4,5,6])
x
set([1, 2, 3, 4, 5, 6])
y
set([1, 2, 3, 4, 5, 6])



x=set([1,2,3])
y=x
x=x|set([4,5,6])
x
set([1, 2, 3, 4, 5, 6])
y
set([1, 2, 3])  # why does the value of y remain unchanged.

因为 x|=set([4,5,6]) 是原地操作,而 x=x|set([4,5,6]) 则是创建一个新对象的赋值操作。 - roganjosh
@roganjosh 你知道为什么要做到就地修改吗?这是令人困惑的部分,我认为。当遇到这个表达式时,我会假设一个新的集合被创建,因为我的心理模型是 v (op) = x 只是 v = v (op) x 的简写。它似乎不符合 Python 的风格,或者我可能不够荷兰化。 - JohanL
@Johan 我认为这没有什么不符合 Python 风格的地方。如果我不关心 y 的变化,那么绑定到被改变的对象上对我来说并不重要。在这种情况下,y = x 是最不符合 Python 风格的,因为它在这个上下文中是一个无意义的名称。对于像 numpy 这样需要速度的东西,类似这样的原地操作非常有意义。 - roganjosh
1个回答

4

在这里,你正在创建一个新的set并将其分配给x

x = x | set([4, 5, 6])

从这里开始,yx 相互独立(它们是不同 set 的名称)。

另一方面,在第一个示例中的原地赋值并没有创建新的 set;它只是修改了当前实例。

x |= set([4, 5, 6])

现在y仍然指向与x相同的set。通过打印可以看出区别。

 print(id(x))
 print(id(y))

赋值前后的差异可以在pythontutor.com上进行可视化展示,这可能具有启发性。


我之前说的一切都适用于可变对象(例如set)。对于不可变对象,就地赋值的行为与'正常'赋值相同;即对于x是一个intx += 1x = x + 1相同。


为什么在变量的情况下不会发生这种情况:
x=2 y=x x+=1 x 3 y 2
- ankit singhal
就像我之前所说的:int是不可变的。x+=1除了返回一个新实例外,没有其他意义;它等同于x = x+1 - hiro protagonist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接