我想调用一个class属性并将其附加到一个列表中。下面是一个简单的脚本:
class class_1():
def __init__(self):
self.x = np.array([0, 0])
def update(self):
self.x += 1
return self.x
cl_1 = class_1()
a = []
for i in range(3):
y = cl_1.update()
print(y)
a.append(y)
print(a)
# output:
[1 1]
[2 2]
[3 3]
[array([3, 3]), array([3, 3]), array([3, 3])]
但我希望[array([1, 1]), array([2, 2]), array([3, 3])]
作为list a
的最终值。我检查了一下python编号没有问题:
class class_2():
def __init__(self):
self.x = 0
def update(self):
self.x += 1
return self.x
cl_2 = class_2()
a = []
for i in range(3):
y = cl_2.update()
print(y)
a.append(y)
print(a)
#output
1
2
3
[1, 2, 3]
发布于 2018-08-03 05:29:55
与Python整数不同,numpy数组确实允许就地修改。对于一个不可变的Python整数,x += 1
和x = x + 1
具有相同的结果。在这两种情况下,x
都被重新绑定到一个新的整数对象。
在对numpy数组执行self.x += 1
操作时,不会更改self.x
指向的引用。不分配新的数组,而是递增现有数组的内部缓冲区中的每个元素。请注意,赋值仍然会发生,但引用与前面相同。
要在此上下文中模拟整数的行为,请显式写出所需的操作:
self.x = self.x + 1
在本例中,self.x + 1
是一个全新的数组,然后可以将其作为整数重新赋值给self.x
。
当涉及到如何修复代码时,您有两个选择:
update
方法,如下所示。在某些方面,这种解决方案是最干净的,因为它最小化了对外部引用的影响。同时,你可能不想每次都创建一个新的副本。a.append(y)
,而是doa.append(y.copy())
或者,立即制作副本:
Y= cl_2.update().copy()
TL;DR
这里发生了一个最常见的初学者陷阱:从对同一可变对象的引用创建一个列表,然后对该对象进行变异。正如预期的那样,所有引用都将以对象的最后一个值结束。
https://stackoverflow.com/questions/51662051
复制相似问题