Python 如何调用np.array的值而不是内存地址?
在下面的代码中,我打算创建一个从空列表开始的列表 通过附加(随机)numpy数组。对于一个临时变量,我初始化了一个numpy数组变量“sample_pt”,它作为一个临时变量来保存一个(随机)numpy数组。虽然我希望有一个随机numpy数组的列表,但输出是一个填充了相同(最终)numpy数组的列表。我怀疑通过“变量名”调用numpy数组会返回其内存地址。我走的方向对吗,或者有什么好知道的吗 [守则]Python 如何调用np.array的值而不是内存地址?,python,arrays,numpy,Python,Arrays,Numpy,在下面的代码中,我打算创建一个从空列表开始的列表 通过附加(随机)numpy数组。对于一个临时变量,我初始化了一个numpy数组变量“sample_pt”,它作为一个临时变量来保存一个(随机)numpy数组。虽然我希望有一个随机numpy数组的列表,但输出是一个填充了相同(最终)numpy数组的列表。我怀疑通过“变量名”调用numpy数组会返回其内存地址。我走的方向对吗,或者有什么好知道的吗 [守则] import numpy as np sample_pt=np.array([0.]) #
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)
但这可以大大简化
首先,与其创建一个0为1的数组,然后替换该0,为什么不创建一个所需元素的数组呢
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中的工作方式 首先,暂时忘记“内存地址”:
- 对象是堆中某个位置的值,具有类型。你不在乎在哪里
- 变量没有内存地址或类型;它们只是某些名称空间(全局、局部、某些实例的属性等)中引用某个值的名称
a=b
时,这意味着a
现在是与b
相同值的另一个名称。如果你想要一份副本,你必须明确要求一份副本
现在,如果你看看CPython是如何在引擎盖下实现的:
- CPython解释器将所有对象表示为指向
结构的指针,这些结构总是在堆上分配的PyObject
- 变量只是
中的字符串键,由模块(用于全局变量)、实例(用于属性)或其他任何内容拥有。dict
中的值与其他对象一样。这意味着,在幕后,哈希表中实际存储的是指向键中变量名的字符串对象的指针,以及指向在值中指定的任何值的指针dict
- 对于局部变量有一种特殊的优化,包括存储在框架上的一组对象指针,但通常不必担心这一点
- 闭包捕获还有另一个特殊的技巧,包括指向单元格对象的指针,这些指针包含指向实际对象的指针,您甚至不必经常担心这些
正如您所见,思考指针更难理解,而且可能会产生误导,除非您真正关心CPython在幕后是如何工作的。重复的一点是,在列表中附加相同的可变对象是危险的。如果使用列表附加,则每次创建一个新对象。