List comprehensions and tuples in Julia

Guards (if) are now available in Julia v0.5 (currently in the release-candidate stage):

julia> v1 = [1, 2, 3];

julia> v2 = [4, 5, 6];

julia> v3 = [(a, b) for a in v1, b in v2 if a+b > 7]
3-element Array{Tuple{Int64,Int64},1}:
 (3,5)
 (2,6)
 (3,6)

Note that generators are also now available:

julia> g = ( (a, b) for a in v1, b in v2 if a+b > 7 )
Base.Generator{Filter{##18#20,Base.Prod2{Array{Int64,1},Array{Int64,1}}},##17#19}(#17,Filter{##18#20,Base.Prod2{Array{Int64,1},Array{Int64,1}}}(#18,Base.Prod2{Array{Int64,1},Array{Int64,1}}([1,2,3],[4,5,6])))

Another option similar to the one of @DanGetz using also Iterators.jl:

function expensive_fun(a, b)
    return (a + b)
end

Then, if the condition is also complicated, it can be defined as a function:

condition(x) = x > 7

And last, filter the results:

>>> using Iterators
>>> result = filter(condition, imap(expensive_fun, l1, l2))

result is an iterable that is only computed when needed (inexpensive) and can be collected collect(result) if required.

The one-line if the filter condition is simple enough would be:

>>> result = filter(x->(x > 7), imap(expensive_fun, l1, l2))

Note: imap works natively for arbitrary number of parameters.


Perhaps something like this:

julia> filter(pair -> pair[1] + pair[2] > 7,  [(i, j) for i in l1, j in l2])
3-element Array{Tuple{Any,Any},1}:
 (3,5)
 (2,6)
 (3,6)

although I'd agree it doesn't look like it ought to be the best way...


Using the very popular package Iterators.jl, in Julia:

using Iterators       # install using Pkg.add("Iterators")
filter(x->sum(x)>7,product(l1,l2))

is an iterator producing the pairs. So to get the same printout as the OP:

l3iter = filter(x->sum(x)>7,product(l1,l2))
for p in l3iter println(p); end

The iterator approach is potentially much more memory efficient. Ofcourse, one could just l3 = collect(l3iter) to get the pair vector.

@user2317519, just curious, is there an equivalent iterator form for python?