Reputation: 33
I would like to use Julia's map
function to mimic a nested list comprehension. This ability would be particularly useful for parallel mapping (pmap
).
For example, this nested list comprehension
[x+y for x in [0,10] for y in [1,2,3]]
produces the nice result
6-element Array{Int64,1}:
1
2
3
11
12
13
and this
[x+y for x in [0,10], y in [1,2,3]]
produces the equally nice
2×3 Array{Int64,2}:
1 2 3
11 12 13
Either of these outcomes are satisfactory for my purposes.
Now here is my best effort at replicating these outcomes with map
map([0,10]) do x
map([1,2,3]) do y
x + y
end
end
which yields the correct results, just not in a form I admire:
2-element Array{Array{Int64,1},1}:
[1, 2, 3]
[11, 12, 13]
Now I know there are brute-force ways get the outcome I want, such as hcat
/vcat
'ing the output or manipulating the input into a matrix, but I'd like to know if there exists a solution as elegant as the nested list comprehension.
Upvotes: 3
Views: 589
Reputation: 91
You could use Iterators.product
:
julia> map(t -> t[1]+t[2], Iterators.product([0,10], [1,2,3]))
2×3 Array{Int64,2}:
1 2 3
11 12 13
Iterators.product
returns an iterator whose elements are tuples.
(It's a shame the anonymous function above couldn't be written (x,y) -> x+y
)
Upvotes: 0
Reputation: 69949
The simplest way I can think of is to use comprehensions and combine them with map
(low benefit) or pmap
(here you get the real value).
On Julia 0.7 (use the fact that in this release you have destructuring in function arguments functionality):
julia> map(((x,y) for x in [0,10] for y in [1,2,3])) do (x,y)
x+y
end
6-element Array{Int64,1}:
1
2
3
11
12
13
julia> map(((x,y) for x in [0,10], y in [1,2,3])) do (x,y)
x+y
end
2×3 Array{Int64,2}:
1 2 3
11 12 13
On Julia 0.6.2 (less nice):
julia> map(((x,y) for x in [0,10] for y in [1,2,3])) do v
v[1]+v[2]
end
6-element Array{Int64,1}:
1
2
3
11
12
13
julia> map(((x,y) for x in [0,10], y in [1,2,3])) do v
v[1]+v[2]
end
2×3 Array{Int64,2}:
1 2 3
11 12 13
Upvotes: 4