Append!() with Tuple and Dict

question

#1

Why

x = Any[1,2]
append!(x,Dict("a"=>1,"b"=>2))
append!(x,("j","k"))
println(x)

print Any[1, 2, "b"=>2, "a"=>1, "j", "k"]?

In python

x = [1,2]
x.append({"a":1,"b":2})
x.append(("a","b"))
print(x)

print [1, 2, {'a': 1, 'b': 2}, ('a', 'b')]

Also Base.Iterators.flatten
[e for e in Base.Iterators.flatten([1,2,Dict("a"=>1,"b"=>2),("j","k")])]
–> Any[1, 2, "b"=>2, "a"=>1, "j", "k"]


#2

Python’s append is push!.


#3
x = Any[1, 2]
push!(x, Dict("a"=>1, "b"=>2))
push!(x, ("j", "k"))

println(x)
Any[1, 2, Dict("b"=>2,"a"=>1), ("j", "k")]

#4

Sorry, python was a bad example!
I know push!
My question is: why append! does’t works like vcat?

I expected the same result for

x = Any[]
append!(x,[1,2])
append!(x,Dict("a"=>1,"b"=>2))
append!(x,("j","k"))
println(x)

result Any[1, 2, "b"=>2, "a"=>1, "j", "k"]

and

x = Any[]
x = vcat(x,[1,2])
x = vcat(x,Dict("a"=>1,"b"=>2))
x = vcat(x,("j","k"))
println(x)

result Any[1, 2, Dict("b"=>2,"a"=>1), ("j", "k")]
Thanks


#5

append! is a generic operation on container. The argument you add is ALWAYS treated as an iterator and all it’s content is added to the array. There’s no logic for adding an object as element and that’s why there’s push! when you need to treat arbitrary objects as a whole.

vcat is a function for arrays and you should not expect it to work the same way on non-arrays as on arrays since it concatenate in the v(ertical) direction which is only a valid concept for arrays. Therefore, it treats arrays and non-arrays differently (I feel like this is just repeating myself, oh well…).
This works very well most of the case and is only mainly a problem when you want to treat an array as a single element, i.e. getting [[1, 2], [2, 3], [1]] from a = [[1, 2], [2, 3]]; b = [1]. Fortunately, what vcat is doing is roughly equivalent to implicitly wrapping non-array with a vector so you can do that implicitly and get it with [a; [b]]. This should be roughly equivalent to a non-mutating push! for vectors.


#6

Thanks!

I’am working with 1-dimensional arrays as lists.
This function is what i need:

myappend!(v::Vector, e::Vector) = append!(v,e)
myappend!(v::Vector, e::Any) = push!(v,e)

#7

In general, it is not a great idea to treat vectors special like this. (see the problem I mentioned above with vcat doing this). It’s usually better to just specify explicitly what you need and I’ve rarely (never?) found that to be a problem, it’s usually (always?) very clear at the call site what the caller want. Doing this mainly makes your code not able to handle vector of vector nicely.