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

2024-03-28 22:42:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我想调用一个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]     

Tags: inselfforoutputreturn属性initcl
1条回答
网友
1楼 · 发布于 2024-03-28 22:42:48

与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

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

相关问题 更多 >