为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

米琪卡哇伊 2021-05-07 18:28:41
我想调用一个class属性,并将其附加到列表中。这是一个简单的脚本:class class_1():    def __init__(self):        self.x = np.array([0, 0])    def update(self):        self.x += 1        return self.xcl_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.xcl_2 = class_2()a = []for i in range(3):    y = cl_2.update()    print(y)    a.append(y)print(a)#output123[1, 2, 3]
查看完整描述

1 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

与Python整数不同,numpy数组实际上允许就地修改。使用不可变的Python整数,x += 1x = x + 1具有相同的结果。在这两种情况下,x都是反弹到一个新的整数对象。

当你做self.x += 1一个numpy的数组,你就不会更改引用该self.x点。没有分配新的数组,而是现有数组的内部缓冲区中的每个元素都增加。请注意,分配仍然会发生,但是引用与以前相同。

要在此上下文中模拟整数的行为,请明确写出所需的操作:

self.x = self.x + 1

在这种情况下self.x + 1是一个全新的数组,然后可以将其重新分配self.x为整数。

关于如何修复代码,您有两个选择:

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

  2. 如果您想在大多数情况下避免创建不必要的副本(或者至少可以控制何时创建副本),请使用@DYZ的建议。代替a.append(y),做

    a.append(y.copy())

    或者,立即复制:

    y = cl_2.update().copy()

TL; DR

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


查看完整回答
反对 回复 2021-05-18
  • 1 回答
  • 0 关注
  • 228 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信