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

NumPy ndarrays 真的是可变的吗?

NumPy ndarrays 真的是可变的吗?

幕布斯7119047 2022-12-20 14:57:25
这是我的第一个代码片段。运行时,它不会抛出断言错误。import numpy as npthis_arr = np.ones(10)next_arr = this_arrnext_arr *= 2assert np.array_equal(this_arr, next_arr)这是我的第二个代码片段。运行时,它会抛出一个断言错误。import numpy as npthis_arr = np.ones(10)next_arr = this_arrnext_arr = next_arr * 2assert np.array_equal(this_arr, next_arr)这种行为让我感到困惑。我对第一个代码片段的理解是,我将名称初始化this_arr为指向某个内存位置的值。然后,当我初始化名称next_arr以指向相同内存位置的相同值时。因此,当我改变指向的值时next_arr,指向的值this_arr也应该改变。这种行为是 Ned Batchelder在此处创造的“Mutable-Presto-Chango” 。但是,第二个代码片段不会以这种方式运行。起初,我认为也许*=运算符在操作符更改时不会以某种方式更改值在内存中的位置*。但是后来我回过头来看第一个片段,发现 和 的内存位置在this_arr这里next_arr也不同!鉴于此,程序如何“知道”更改值this_arr以匹配已更改的值next_arr?另外,为什么程序“不知道”更改第二个代码片段中的值?编辑:作为后续问题:所以即使 next_arr 和 this_arr 有不同的内存位置,python 初始化的两者之间有一些潜在的联系?
查看完整描述

2 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

我更喜欢谈论对象和引用,而不是价值观。所以我会把你的第一个代码描述为:

这将创建一个ndarray对象,并将其(或对它的引用)分配给this_arr

this_arr = np.ones(10)

并将相同的引用分配给next_arr

next_arr = this_arr

所以next_arrthis_arr引用同一个对象。

然后对数组对象进行“就地”更改。使用哪个名称并不重要。

next_arr *= 2

这两个名称仍然引用同一个数组对象。(在幕后做*=一些缓冲,但数组对象和数据缓冲区位置保持不变)。另一个可变的变化是next_arr[1] = 10(对于列表对象也是如此)。

next_arr = next_arr * 2

乘法生成一个新的数组对象。那被分配给next_arr,打破了与先前引用对象(this_arr仍然引用)的任何链接。

如果id(this_arr)id(next_arr)相同,则引用该对象。大致id是一个位置 - 但与c. 但要注意随着时间的推移比较 id;它们可以被重复使用。

arr.__array_interface__是另一个方便的工具。If 有一个data键告诉我们数组的底层数据缓冲区位于何处。但是要了解您需要了解数组的存储方式以及 和 之间的view区别copy


查看完整回答
反对 回复 2022-12-20
?
哔哔one

TA贡献1854条经验 获得超8个赞

当您初始化 next_arr=this_arr 时,它实际上所做的是将 this_arr 位置的值复制到 next_arr 的新位置。这是我对这段代码的理解,否则这种行为是不可能的



查看完整回答
反对 回复 2022-12-20
  • 2 回答
  • 0 关注
  • 78 浏览
慕课专栏
更多

添加回答

举报

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