我希望能够以向量化的方式将一个元组数组喷射到一个函数中。例如,如果我具有以下功能,
function foo(x, y)
x + y
end
和以下元组数组,
args_array = [(1, 2), (3, 4), (5, 6)]
然后我可以使用列表理解来获得所需的结果:
julia> [foo(args...) for args in args_array]
3-element Array{Int64,1}:
3
7
11
但是,我希望能够对此操作使用点矢量化表示法:
julia> foo.(args_array...)
ERROR: MethodError: no method matching foo(::Int64, ::Int64, ::Int64)
但是如您所见,该特定语法不起作用。有矢量化的方法可以做到这一点吗?
答案 0 :(得分:8)
foo.(args_array...)
不起作用,因为它正在这样做:
foo.((1, 2), (3, 4), (5, 6))
# which is roughly equivalent to
[foo(1,3,5), foo(2,4,6)]
换句话说,它将args_array
的每个元素作为一个单独的参数,然后在这些参数上广播foo
。您想直接在元素上广播foo
。问题在于运行:
foo.(args_array)
# is roughly equivalent to:
[foo((1,2)), foo((3,4)), foo((5,6))]
换句话说,广播语法只是将每个元组作为单个参数传递给foo
。我们可以使用一个简单的中间函数来解决该问题:
julia> bar(args) = foo(args...);
julia> bar.(args_array)
3-element Array{Int64,1}:
3
7
11
现在,这就是您想要的!如果不想的话,甚至不需要构造第二个参数。这是完全等效的:
julia> (args->foo(args...)).(args_array)
3-element Array{Int64,1}:
3
7
11
实际上,您可以很容易地对此进行概括:
julia> splat(f) = args -> f(args...);
julia> (splat(foo)).(args_array)
3-element Array{Int64,1}:
3
7
11
答案 1 :(得分:1)
您可以zip
args_array
,它可以有效地对元组数组进行转置:
julia> collect(zip(args_array...))
2-element Array{Tuple{Int64,Int64,Int64},1}:
(1, 3, 5)
(2, 4, 6)
然后,您可以在元组的转置数组(实际上是迭代器)上广播foo
:
julia> foo.(zip(args_array...)...)
(3, 7, 11)
但是,这将返回一个元组而不是一个数组。如果需要将返回值作为数组,则可以使用以下任何一种含糊的解决方案:
julia> foo.(collect.(zip(args_array...))...)
3-element Array{Int64,1}:
3
7
11
julia> collect(foo.(zip(args_array...)...))
3-element Array{Int64,1}:
3
7
11
julia> [foo.(zip(args_array...)...)...]
3-element Array{Int64,1}:
3
7
11
答案 2 :(得分:0)
怎么样
[foo(x,y) for (x,y) in args_array]