WallyKlondike
WallyKlondike

Reputation: 33

How to use map in Julia to mimic a nested list comprehension?

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

Answers (2)

Greg
Greg

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

Bogumił Kamiński
Bogumił Kamiński

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

Related Questions