# Question regarding push! and array of arrays

Hello, I have a question about a very unexpected behavior I encountered, I’d like an ELI5.

Why does this:

``````vi = fill(Int[], 5)
vi = [5,6]
push!(vi, 9)
``````

result in

`````` 
[5, 6]



``````

`````` []
[5, 6]

[]
[]
``````

?

While we’re at it, why was the `[5, 6]` part left unchanged, unlike all the other elements?

BTW, my intention was to use a dynamic data structure consisting of `n` (determined at run time) independent dynamically created arrays, what’s the right way to do this (in case I’m doing it wrong)?

(Julia 1.5.3)

``````julia> vi = [Int[] for _=1:5]
5-element Array{Array{Int64,1},1}:
[]
[]
[]
[]
[]

julia> vi = [5,6]
2-element Array{Int64,1}:
5
6

julia> push!(vi, 9)
1-element Array{Int64,1}:
9

julia> vi
5-element Array{Array{Int64,1},1}:
[]
[5, 6]

[]
[]
``````

Long story short, `fill` with `Int` arrays will just add “references” to the same array, not separate copies of arrays.

4 Likes

The reason is order of operations. This is a common trip-up. In the expression:

``````fill(Int[], 5)
``````

First the the array `Int[]` is created, then the “outer” (5-element) array is created, and each element of that array references the empty `Int[]` array. These are all references to the same array, so when you modify one of them (by pushing) you modify them all.

It breaks down like this:

``````x = Int[]
vi = [x for _ in 1:5]  # vi == [[], [], [], [], []]
push!(x, 1)            # vi == [, , , , ]
vi = [5, 6]         # vi == [, [5, 6], , , ]
``````
3 Likes

Thank you both! I learned something.

You might be looking for

``````julia> vi = [Int[] for _ ∈ 1:5];

julia> vi = [5, 6]
2-element Vector{Int64}:
5
6

julia> push!(vi, 9)
1-element Vector{Int64}:
9

julia> vi
5-element Vector{Vector{Int64}}:
[]
[5, 6]

[]
[]
``````

Here the comprehension creates distinct `[]` objects.