Adham
Adham

Reputation: 342

Julia list comprehension changes the type

Suppose we have a Vector of tuples (Int64, Int64) in julia:

In [1] xx = [(1, 2), (3, 4), (5, 6)]
       typeof(xx) == Vector{(Int64, Int64)}
Out[1] true

Now I want to construct a new vector of the first indices of the tuples.

In [2] indices = [x[1] for x in xx]
       typeof(indices)
Out[2] Array{Any, 1}

I expect it to be an Array{Int64, 1} type. How can I fix this?

edit: I am using 0.3.9.

Upvotes: 3

Views: 471

Answers (2)

Felipe Lema
Felipe Lema

Reputation: 2718

You can also use map and preserve the type:

#passing a lambda that takes the 1st element, and the iterable
inds = map( (x)-> x[1], xx)

Upvotes: 1

Colin T Bowers
Colin T Bowers

Reputation: 18560

function f()
    xx = [(1, 2), (3, 4), (5, 6)]
    inds = [ x[1] for x in xx ]
    return(inds)
end

y = f()
typeof(y)

The last line of code returns Array{Int64, 1}.

The problem here is that you are working in global scope. For Julia's type inference to be able to do its magic, you need to work in a local scope. In other words, wrap all your code in functions. This rule is very, very, important, but, having come from a MatLab background myself, I can see why people forget it. Just remember, 90% of questions saying "Why is my Julia code slow?" occur because the user was working in global scope, not local scope.

ps, even in local scope, type inference of loop comprehensions can stumble in particularly complex cases. This is a known issue and is being worked on. If you want to provide the compiler with some "help" you can do something like:

inds = Int[ x[1] for x in xx ]

Upvotes: 11

Related Questions