Empty vector loop

Hi. I’m looking to code the following pseudo-loop in Julia.

x=[]; # empty vector
for t in 0:2
x=[x t] 
end

The answer should be x=[0 1 2]. The error I get is this.

DimensionMismatch(“mismatch in dimension 1 (expected 0 got 1)”)

Stacktrace:
[1] _cs at ./abstractarray.jl:1501 [inlined]
[2] _cshp at ./abstractarray.jl:1497 [inlined]
[3] cat_shape at ./abstractarray.jl:1476 [inlined] (repeats 2 times)
[4] _cat_t at ./abstractarray.jl:1521 [inlined]
[5] #cat_t#110 at ./abstractarray.jl:1518 [inlined]
[6] _cat at ./abstractarray.jl:1516 [inlined]
[7] #cat#111 at ./abstractarray.jl:1654 [inlined]
[8] hcat(::Array{Any,1}, ::Int64) at ./abstractarray.jl:1634
[9] top-level scope at ./In[559]:3
[10] include_string(::Function, ::Module, ::String, ::String) at ./loading.jl:1091
[11] execute_code(::String, ::String) at /Users/Name/.julia/packages/IJulia/a1SNk/src/execute_request.jl:27
[12] execute_request(::ZMQ.Socket, ::IJulia.Msg) at /Users/Name/.julia/packages/IJulia/a1SNk/src/execute_request.jl:86
[13] #invokelatest#1 at ./essentials.jl:710 [inlined]
[14] invokelatest at ./essentials.jl:709 [inlined]
[15] eventloop(::ZMQ.Socket) at /Users/Name/.julia/packages/IJulia/a1SNk/src/eventloop.jl:8
[16] (::IJulia.var"#15#18")() at ./task.jl:356

The problem seems to be in the creation of the empty vector, but the alternatives I have tried (zeros(0), Vector{Float64} etc.) don’t seem to work either. I am using Julia 1.5.3. Thank you.

You want push! instead of what you are currently doing

x = []
for t in 0:2
    push!(x, t)
end
1 Like

If you plan to make a vector of Ints, you should specify the element type:

x = Int[]

Otherwise, you will end up with a Vector{Any}, which is likely to have poor performance.

1 Like

Thanks, that seems to have worked.

Thanks for the indication.

Just a comment, note that the error is associated to the fact that to set a vector in Julia you need a comma. Because this works:

julia> x = []
       for t in 0:2
           x = [ x, t ] # add comma here
       end

julia> x
2-element Vector{Any}:
  Any[Any[Any[], 0], 1]
 2

But note that this is not what you expected, of course, because when you do x = [ x, t ] the first element will be the vector x, thus this will become a vector of nested empty vectors, etc.

You would need to expand the vector into its elements inside the loop, doing this:

julia> x = []
       for t in 0:2
           x = [ x..., t ] # the ... is called the splatting operator
       end
       x
3-element Vector{Int64}:
 0
 1
 2

Now you get what you expected.

None of these things is betther than push into a properly typed vector Int[], though, because in these cases I show you are creating a new vector at every iteration of the loop, instead of just adding elements to an existing vector.

1 Like

This works, but splatting is very inefficient when used with containers whose size isn’t known to the compiler. In fact, all you actually need is the ; operator, which already concatenates vertically:

julia> x = [1, 2];

julia> x = [x; 3]
3-element Vector{Int64}:
 1
 2
 3
3 Likes

You might as well just write [x t] like the OP did, since this does horizontal concatenation.

But push! would be better still.

In that specific code that does not work.

Are you saying vcat works, but not hcat? (I can’t test it on my phone.)

It was the error OP was getting:

julia> x = []
       for i in 1:2
           x = [ x i ]
       end
ERROR: DimensionMismatch("mismatch in dimension 1 (expected 0 got 1)")

which is this:

julia> hcat([],1)
ERROR: DimensionMismatch("mismatch in dimension 1 (expected 0 got 1)")

(one could argue that both hcat and vcat should return the same thing, which is a vector with 1 element - not sure if there is a deep consistency reason for hcat not work)

julia> x = zeros(Int, 1, 0)
1×0 Matrix{Int64}

julia> for i in 1:2
           x = [ x i ]
       end

julia> x
1×2 Matrix{Int64}:
 1  2
1 Like

Thank you for the explanation.

Thank you for the clarification.

Thanks a lot.