gpt4 book ai didi

Python使用numpy数组类型附加类属性

转载 作者:行者123 更新时间:2023-12-01 09:10:52 24 4
gpt4 key购买 nike

我想调用一个类属性并将其附加到列表中。这是一个简单的脚本:

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])]作为列表 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]

最佳答案

与 Python 整数不同,numpy 数组确实允许就地修改。对于不可变的 Python 整数,x += 1x = x + 1 具有相同的结果。在这两种情况下,x 都会反弹到整数对象。

当您对 numpy 数组执行 self.x += 1 时,您不会更改 self.x 指向的引用。不会分配新数组,而是增加现有数组内部缓冲区中的每个元素。请注意,分配仍然会发生,但引用与之前相同。

要在这种情况下模拟整数的行为,请显式写出您想要的操作:

self.x = self.x + 1

在本例中,self.x + 1 是一个全新的数组,然后可以将其作为整数重新分配给 self.x

当涉及到如何修复代码时,您有两种选择:

  1. 如果您同意每次创建一个新数组并丢弃以前的数组,请更改 update 方法,如上所示。在某些方面,这个解决方案是最干净的,因为它最大限度地减少了对外部引用的影响。同时,您可能不想每次都创建新副本。

  2. 如果您想在大多数情况下避免创建不必要的副本(或至少控制何时制作副本),请使用 @DYZ's suggestion 。而不是 a.append(y),而是

    a.append(y.copy())

    或者立即制作副本:

    y = cl_2.update().copy()

TL;DR

最常见的初学者陷阱之一就发生在这里:从对同一可变对象的引用创建一个列表,然后改变该对象。正如预期的那样,所有引用都将以对象的最后一个值结束。

关于Python使用numpy数组类型附加类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51662051/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com