在下面的代码中,我打算从空的列表开始 通过附加(随机)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])]
答案 0 :(得分:0)
我不知道你的意思是"呼叫值",或者#34;而不是记忆地址",或......你问题的大部分内容。
但问题很简单。您反复追加相同的数组,而不是创建新数组。
如果要创建新阵列,则必须明确地执行此操作。这是微不足道的;只需将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)
但这可以大大简化。
首先,不是创建一个零的数组然后替换零,为什么不只是创建一个你想要的元素的数组呢?
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如何在幕后实现的东西:
PyObject
结构的指针,这些结构始终在堆上分配。dict
中的字符串键,由模块(对于全局变量),实例(对于属性)或其他任何东西拥有。 dict
中的值只是与其他任何对象一样的对象。这意味着,在封面下,实际存储在散列表中的是指向键中变量名称的字符串对象的指针,以及指向您在值中分配的任何值的指针。正如你所看到的,思考这些指针更难理解,并且可能具有误导性,除非你真的关心CPython如何在幕后工作。