是什么导致Python在为字典中的值赋值时出现这种奇怪的结果?

是什么导致Python在为字典中的值赋值时出现这种奇怪的结果?,python,numpy,dictionary,variable-assignment,Python,Numpy,Dictionary,Variable Assignment,我最近将某些代码中的一个bug简化为以下行为的结果: >>> arr = np.zeros(10) >>> value = 0 >>> dictionary = {"key":[arr,value]} >>> dictionary["key"][0] array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) >>> dictionary["key"]

我最近将某些代码中的一个bug简化为以下行为的结果:

>>> arr = np.zeros(10)
>>> value = 0
>>> dictionary = {"key":[arr,value]}
>>> dictionary["key"][0]
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
>>> dictionary["key"][1]
0
>>> dictionary["key"][0]+=1
>>> dictionary["key"][1]+=1
>>> dictionary["key"][0]   
array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])
>>> dictionary["key"][1]   
1
>>> arr
array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])
>>> value
0
导致:

>>> dictionary["key"][0] is arr
True
>>> dictionary["key"][1] is value 
False

可能是一个愚蠢的问题,但这是什么原因?

在numpy数组的情况下,在字典中为同一个对象分配了名称arr。因此,当您修改它时,您会看到这两个对象都出现了更改,毕竟它们是同一个对象,并且numpy数组是可变的

对于整数,当您执行dictionary[key][1]+=1时,您正在dictionary内创建一个新的整数,这是因为整数是不可变的[1]。这意味着两个整数value和dictionary[key][1]是不同的对象,因此其中一个被修改,而另一个未被修改


[1] 它可能看起来像x=2;x+=1在同一个对象上运行,毕竟+=应该执行就地操作,但这不是因为不变性。在幕后,您实际上是在用一个新的整数对象重新绑定x,因此它们具有相同的名称,但是不同的对象。

对于numpy数组,您在字典中使用名称arr分配了相同的对象。因此,当您修改它时,您会看到这两个对象都出现了更改,毕竟它们是同一个对象,并且numpy数组是可变的

对于整数,当您执行dictionary[key][1]+=1时,您正在dictionary内创建一个新的整数,这是因为整数是不可变的[1]。这意味着两个整数value和dictionary[key][1]是不同的对象,因此其中一个被修改,而另一个未被修改


[1] 它可能看起来像x=2;x+=1在同一个对象上运行,毕竟+=应该执行就地操作,但这不是因为不变性。在幕后,您实际上是在用一个新的整数对象重新绑定x,因此它们具有相同的名称,但是不同的对象。

答案在于numpy数组可变和整数不可变之间的区别。执行此操作时:

dictionary["key"][0]+=1
dictionary["key"][1]+=1
这改变了numpy数组的位置,因此仍然是同一个对象

执行此操作时:

dictionary["key"][0]+=1
dictionary["key"][1]+=1

它不能改变不可变的整数,因此分配了一个新对象,这就是它返回False的原因。

答案在于numpy数组可变和整数不可变之间的区别。执行此操作时:

dictionary["key"][0]+=1
dictionary["key"][1]+=1
这改变了numpy数组的位置,因此仍然是同一个对象

执行此操作时:

dictionary["key"][0]+=1
dictionary["key"][1]+=1
它不能改变不可变的整数,因此分配了一个新对象,这就是为什么返回False。

np。数组对象是可变的,int对象不是。添加到整数实际上会创建一个新对象,添加到数组会更新旧对象。np.array对象是可变的,int对象不是。添加到整数实际上会创建一个新对象,添加到数组会更新旧对象。