gpt4 book ai didi

julia - 为什么在 Julia 中使用 for 循环和列表理解更新全局向量会产生不同的结果?

转载 作者:行者123 更新时间:2023-12-02 17:58:27 26 4
gpt4 key购买 nike

我在下面粘贴了完整的 MWE。由于有点长,我先分解一下。

任务:我有一个全局向量vec,它将在循环中随机更新。我有一个全局向量 vecvec(向量的向量),它应该存储 vec 的历史记录。

尝试的解决方案(不起作用):函数make_vec()随机更新vec。我将其放入循环中,如下所示。

for i in 1:5
make_vec()
println(vec)
push!(vecvec,vec)
end

运行这个(或者更确切地说是下面的MWE),可以从打印输出中看到,全局变量vec在每一轮中都由make_vec()更新按预期循环。但是:

问题 1:为什么收集的历史记录中的所有向量 vecvec 都相同?

我可以猜测这个问题的答案,即 push! 不会推送实际的向量 vec 而只是对 vec 的引用。因此,当我在循环完成后检查 vecvec 时,所有条目都与 vec 的最后更新相同。

但这又提出了另一个问题。

问题 2:在下面的 MWE 中,我添加了 make_vec() 的两个替代实现。特别是,make_vec2()(make_vec3() 类似)与 make_vec() 相同,但用列表理解替换了 for 循环。为什么用 make_vec2() 替换循环中的 make_vec() 会产生不同的结果(实际上是期望的结果)?

vec = [1,2,3]
vecvec = []

function make_vec()
for i in 1:3
vec[i] = rand(0:9)
end
end

function make2_vec()
global vec = [rand(0:9) for i=1:3]
end

function make3_vec()
local vec3 = [1,2,3]
for i in 1:3
vec3[i] = rand(0:9)
end
global vec = vec3
end


for i in 1:5
make_vec() # make_vec2 and make_vec3 would give the desired result, but not make_vec
println(vec)
push!(vecvec,vec)
end

print(vecvec)

我在内核为 1.8.3 的 Jupyter 笔记本中运行此程序。

最佳答案

    for i in 1:3
vec[i] = rand(0:9)
end

您不会更改 vec 绑定(bind)到的值(在本例中为数组)。相反,您只需更改存储在数组中的元素。这通常称为就地更新。

另一方面:

    global vec = [rand(0:9) for i=1:3]

分配一个新向量并将这个新值绑定(bind)到vec变量。这意味着您不是更新某个容器中的值,而是替换该容器。

与以下内容相同:

    local vec3 = [1,2,3]
for i in 1:3
vec3[i] = rand(0:9)
end
global vec = vec3

local vec3 = [1,2,3] 分配新容器,global vec = vec3 将此新容器绑定(bind)到 vec 变量.

这清楚吗?


作为旁注 - 最好不要使用 vec 作为变量名称,因为 vec 是在 Base Julia 中定义的函数名称。

关于julia - 为什么在 Julia 中使用 for 循环和列表理解更新全局向量会产生不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75052389/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com