Alec
Alec

Reputation: 4482

Why do these two different ways of constructing an array produce different behaviors?

When I construct a 2 element array in two different ways(e.g. a and b, I get two different results when I add an element to one of the inner arrays. This also happens with append!. Based on the output after constructing each, I'd expect them to be exactly the same?

julia> a = [[],[]]
2-element Array{Array{Any,1},1}:
 Any[]
 Any[]

julia> push!(a[1],1.0)
1-element Array{Any,1}:
 1.0

julia> a
2-element Array{Array{Any,1},1}:
 Any[1.0]
 Any[]

julia> b = fill([],2)
2-element Array{Array{Any,1},1}:
 Any[]
 Any[]

julia> push!(b[1],1.0)
1-element Array{Any,1}:
 1.0

julia> b
2-element Array{Array{Any,1},1}:
 Any[1.0]
 Any[1.0]

Upvotes: 2

Views: 148

Answers (2)

Frames Catherine White
Frames Catherine White

Reputation: 28212

Take a look at the following examples. Hopefully the behavior is as you expect.

Input[1]:

a_1 = []
a_2 = []
a = [a_1, a_2]
push!(a_1, 1.0)
@show a_1 
@show a

Output[1]:

a_1 = Any[1.0]
a = Array{Any,1}[Any[1.0],Any[]]

Input[2]

push!(a[1], 2.0)
@show a_1 #Guess what this shows
@show a

Output[2]:

a_1 = Any[1.0,2.0]
a = Array{Any,1}[Any[1.0,2.0],Any[]]

Input[3]:

b_n = []
b = fill(b_n, 2)
push!(b_n, 1.0)
@show b_n 
@show b 

Output[3]:

b_n = Any[1.0]
b = Array{Any,1}[Any[1.0],Any[1.0]]

Input[4]:

push!(b[1], 2.0)
@show b_n #Guess what this shows
@show b

Output[4]

b_n = Any[1.0,2.0]
b = Array{Any,1}[Any[1.0,2.0],Any[1.0,2.0]]

Input[5]:

c_n = []
c = [c_n, c_n]
push!(c_n, 1.0)
@show c_n 
@show c 

Output[5]:

c_n = Any[1.0]
c = Array{Any,1}[Any[1.0],Any[1.0]]

Input[6]:

push!(c[1], 2.0)
@show c_n 
@show c

Output[6]:

c_n = Any[1.0,2.0]
c = Array{Any,1}[Any[1.0,2.0],Any[1.0,2.0]]

So Input[1] is the same as your a, and Input[3] is the same as your b

Each time you put a [] you construct a new Vector.

So in the first case: a=[[],[]] creates a vector containing two new vectors which I call a_1 and a_2 in Input[1]

In the second case: b=fill([],2] creates a vector, which I call b_n in Input[3], and then it fills an vector of length 2, with that vector b_n. This it equivelent to the example in Input[3] (with c). I might as well have said: [b_n, b_n] as said fill(b_n,2)

So it references to the same vector at each position. So changing one, changes the both.

Upvotes: 2

Scott Jones
Scott Jones

Reputation: 1750

fill will create an array initialized with n copies (shallow) of the same object, so that b[1] === b[2], and when you update b[1], you're updating the same object that's also pointed to in b[2].

Upvotes: 4

Related Questions