我想调用一个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])]
作为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 + 1
是一个全新的数组,然后可以将其作为整数重新分配给self.x
。你知道吗对于如何修复代码,您有两种选择:
如果每次都可以创建一个新的数组,并放弃以前的数组,请更改
update
方法,如上图所示。在某些方面,这个解决方案是最干净的,因为它最小化了对外部引用的影响。同时,您可能不希望每次都创建一个新副本。如果您想在大多数情况下避免创建不必要的副本(或者至少可以控制何时制作副本),请使用@DYZ's suggestion。代替
a.append(y)
,做或者,立即复制:
TL;DR
最常见的初学者陷阱之一发生在这里:从对同一可变对象的引用创建一个列表,然后对该对象进行变异。所有引用都将以对象的最后一个值结束,如预期的那样。你知道吗
相关问题 更多 >
编程相关推荐