python - 如何调用 np.array 的值而不是内存地址?
问题描述
在下面的代码中,我打算通过附加(随机)numpy 数组来创建一个从空列表开始的列表。对于一个临时变量,我初始化了一个 numpy 数组变量“sample_pt”,它作为一个临时变量来保存一个(随机)numpy 数组。虽然我希望有一个随机 numpy 数组的列表,但输出是一个填充了相同(最终)numpy 数组的列表。我怀疑通过“变量名”调用一个 numpy 数组会返回它的内存地址。我的方向是否正确,或者有什么值得了解的吗?
[代码]
import numpy as np
sample_pt=np.array([0.]) # initial point
sample_list=[]
number_iter=3
for _ in range(number_iter):
sample_pt[0]=np.random.randn()
sample_list.append(sample_pt)
print(sample_list)
[输出]
[array([-0.78614157])]
[array([0.7172035]), array([0.7172035])]
[array([0.47565398]), array([0.47565398]), array([0.47565398])]
解决方案
我不知道您所说的“调用值”或“而不是内存地址”是什么意思,或者……您问题的大部分内容。
但问题很简单。您一遍又一遍地附加相同的数组,而不是创建新数组。
如果你想创建一个新数组,你必须明确地这样做。这是微不足道的;只需将np.array
构造函数移动到循环中,如下所示:
sample_list=[]
number_iter=3
for _ in range(number_iter):
sample_pt=np.array([0.]) # initial point
sample_pt[0]=np.random.randn()
sample_list.append(sample_pt)
print(sample_list)
但这可以大大简化。
首先,与其创建一个包含 1 个零的数组,然后替换那个零,为什么不直接创建一个包含您想要的元素的数组呢?
sample_pt = np.array([np.random.randn()])
或者,更好的是,为什么不让我们np.random
为您构建阵列呢?
sample_pt = np.random.randn(1)
此时您可以用列表理解替换整个内容:
number_iter = 3
sample_list = [np.random.randn(1) for _ in range(number_iter)]
或者,更好的是,为什么不创建一个 3x1 数组而不是 3 个单元素数组的列表呢?
number_iter = 3
sample_array = np.random.randn((number_iter, 1))
如果您出于某种原因确实需要将其更改为 3 个数组的列表,您可以list
稍后随时调用它:
sample_list = list(sample_array)
……或一开始:
sample_list = list(np.random.randn((number_iter, 1)))
同时,我认为您误解了值和变量在 Python 中的工作方式。
首先,暂时忘记“内存地址”:
- 对象是堆中某处的具有类型的值。你不在乎在哪里。
- 变量没有内存地址或类型;它们只是某个命名空间中的名称(全局变量、局部变量、某个实例的属性等),它们在某处引用某个值。
请注意,这与 C++ 非常不同,C++ 中的变量是类型化的内存位置,而对象位于这些内存位置中。这意味着 Python 中没有“复制构造函数”或“赋值运算符”或类似的东西。当您编写a = b
时,这意味着它a
现在是与 . 相同值的另一个名称b
。如果你想要一份副本,你必须明确要求一份副本。
现在,如果你看看 CPython 是如何在幕后实现的:
- CPython 解释器将所有对象表示为指向
PyObject
结构的指针,这些结构总是在堆上分配。 - 变量只是 a 中的字符串键
dict
,由模块(对于全局变量)、实例(对于属性)或其他任何东西拥有。中的值dict
只是像其他任何对象一样的对象。这意味着,在幕后,实际上存储在哈希表中的是指向键中变量名称的字符串对象的指针,以及指向您在值中分配的任何值的指针。 - 本地有一个特殊的优化,涉及存储在框架上的对象指针数组,但您通常不必担心这一点。
- 闭包捕获还有另一个特殊技巧,涉及指向包含指向实际对象的指针的单元对象的指针,您不必经常担心。
正如你所看到的,考虑指针更难理解,并且可能会产生误导,除非你真的关心 CPython 是如何在幕后工作的。
推荐阅读
- android - 拼车应用程序应该何时计算票价?
- python - 如何在 conda 环境中使用最新的 7.5 cudnn?
- android - 如何重置单选按钮的背景颜色?
- python - 如何在 TensorFlow 2.0 中使用 Dataset.window() 方法创建的窗口?
- apache - 为 mvc 前端控制器设置 .htaccess
- sql - SQL 查询执行时间过长并在列中出现重复项
- python - Django2.1.7 项目 urls.py 无法正常工作(给出 404 错误)
- javascript - 与 $_POST[] 相比,PHP 随机数生成器不工作
- typescript - 使用Vue组件的mocha进行单元测试时基类中的方法不存在
- powershell - 导入多个 csv 文件并在每个 .csv 文件中写入字符串“End”