Julia,使用map多次运行一个函数,

Jim*_*aas 3 integer loops julia

我有一些代码可以正常运行并执行我想要的操作,尽管可能有一个更简单更优雅的解决方案,但这是有效的:

round(Int16, floor(rand(TruncatedNormal(150,20,50,250))))
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用 map 多次执行它时,它会抛出一个错误,指出它不喜欢 Int16 规范,因此:

map(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
Run Code Online (Sandbox Code Playgroud)

抛出这个错误

ERROR: MethodError: objects of type Int16 are not callable
Run Code Online (Sandbox Code Playgroud)

我只想运行它两次(在本例中)并对结果求和。为什么不高兴呢?谢谢。J

dar*_*ack 5

第一个参数map是一个函数。因此,通过您的代码,Julia 正在尝试进行函数调用:

round(Int16, floor(rand(TruncatedNormal(150,20,50,250))))()
Run Code Online (Sandbox Code Playgroud)

但 的输出round(Int16, ...)不是一个函数,而是一个数字,所以你不能调用它。这就是为什么错误显示“Int16 类型的对象不可调用”。您可以使用匿名函数来解决此问题:

map(() -> round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))), 1:2)
Run Code Online (Sandbox Code Playgroud)

“朱利安”的方法是使用理解:

[round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))) for _ in 1:2]
Run Code Online (Sandbox Code Playgroud)

编辑:

如果您要查看sum结果,那么您可以使用看起来像推导式但称为生成器表达式的东西。这基本上就是上面带有[ ]around 表达式的所有内容。sum生成器表达式可以直接在ormean等​​函数中使用。

sum(round(Int16, floor(rand(TruncatedNormal(150,20,50,250)))) for _ in 1:2)
Run Code Online (Sandbox Code Playgroud)

生成器表达式的优点是它们不会为整个数组分配内存。因此,如果您执行此操作 100 次并使用sum上述方法,则无需为 100 个数字分配空间。


这超出了最初的问题,但 OP 想使用in是 1 元素向量的sum表达式。当然,如果输入始终是 1 元素向量,那么我建议像注释一样。但这是一个很好的机会来展示在 Julia 中经常将事物分解为函数的重要性。例如,您可以采用整个表达式并定义一个函数21:2first(x)sum

generatenumbers(n::Integer) = sum(... for _ in 1:n)
Run Code Online (Sandbox Code Playgroud)

其中n是一个标量。然后,如果您有一些奇数数组表达式n(1 元素向量,n多维数组中的许多这样的 s 等),您可以这样做:

generatenumbers.(ns)
# will apply to each element and return same shape as ns
Run Code Online (Sandbox Code Playgroud)

如果脱糖逻辑比按元素应用更复杂,您甚至可以定义:

generatenumbers(ns::AbstractArray) = # ... something more complex
Run Code Online (Sandbox Code Playgroud)

重点是定义一个“原子”函数来清楚地表达您想要的语句或任务,然后使用分派将其应用到实际代码中出现的更复杂的数据结构。这是 Julia 中的一种常见设计模式(不是唯一的选择,但却是一种有效的选择)。