Python使用numpy数组类型附加class属性
我想调用一个class属性并将其附加到列表中。下面是一个简单的脚本:Python使用numpy数组类型附加class属性,python,python-3.x,list,Python,Python 3.x,List,我想调用一个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
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])]
作为lista
的最终值。我检查了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]
与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)
,而是执行以下操作
a.append(y.copy())
或者,立即制作副本:
y = cl_2.update().copy()
最常见的初学者陷阱之一发生在这里:从对同一可变对象的引用创建列表,然后对该对象进行变异。正如预期的那样,所有引用都将以对象的最后一个值结束。这是一个重复,已被询问了一百万次(没有对您的反映,OP),但我似乎找不到一个好的候选锤。基本上,请注意,您总是将引用附加到同一数组。+=的全部意义在于它会就地修改,而不是创建副本。您可以使用
返回self.x.copy()
来避免此问题。@DYZ。或者更清楚地说,拼出self.x=self.x+1
@madpysicast就够了。取决于上下文。