猿问

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

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


米琪卡哇伊
浏览 229回答 1
1回答

慕田峪4524236

与Python整数不同,numpy数组实际上允许就地修改。使用不可变的Python整数,x += 1并x = x + 1具有相同的结果。在这两种情况下,x都是反弹到一个新的整数对象。当你做self.x += 1一个numpy的数组,你就不会更改引用该self.x点。没有分配新的数组,而是现有数组的内部缓冲区中的每个元素都增加。请注意,分配仍然会发生,但是引用与以前相同。要在此上下文中模拟整数的行为,请明确写出所需的操作:self.x = self.x + 1在这种情况下self.x + 1是一个全新的数组,然后可以将其重新分配self.x为整数。关于如何修复代码,您有两个选择:如果可以每次都创建一个新数组并丢弃前一个数组,可以update按上述方法更改方法。在某些方面,此解决方案是最干净的,因为它可以最大程度地减少对外部参考的影响。同时,您可能不想每次都创建一个新副本。如果您想在大多数情况下避免创建不必要的副本(或者至少可以控制何时创建副本),请使用@DYZ的建议。代替a.append(y),做a.append(y.copy())或者,立即复制:y = cl_2.update().copy()TL; DR最常见的初学者陷阱发生在这里:从对同一可变对象的引用创建一个列表,然后对该对象进行突变。如预期的那样,所有引用都将以对象的最后一个值结束。
随时随地看视频慕课网APP

相关分类

Python
我要回答