# How can I do list comprehension for vcat?

**URL:** <https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178>\
**Category:** General Usage\
**Tags:** question\
**Created:** [July 13, 2022, 2:04pm UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178 "2022-07-13T14:04:24Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Phuntsho](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phuntsho/32/46546_2.png) [@Phuntsho](https://discourse.julialang.org/u/Phuntsho)\
**Post date:** [July 13, 2022, 2:04pm UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/1 "2022-07-13T14:04:24Z")

</div>

I have many 1-d lists that I want to concatenate to have a 1-d list, probably in a list comprehension style. Following is how I can achieve using explicit for-loop

```julia
f = []
a = [1,2,3,4,6]
b = [3,4,5,20]
c = [8,4,5,20]
d = [8,1,90,40]
x=[a,b,c,d,a]
for a in x
    f= [f;a]
end
f # I get 22-element Vector which is what I am looking for. 

```

Thank you for your help in advance.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [July 13, 2022, 2:14pm UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/2 "2022-07-13T14:14:28Z")

</div>

```julia
julia> f = vcat(a,b,c,d,a)
22-element Vector{Int64}:
  1
  2
  3
  4
  6
  3
  4
  5
 20
  ⋮
  1
 90
 40
  1
  2
  3
  4
  6

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [July 13, 2022, 2:19pm UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/3 "2022-07-13T14:19:17Z")

</div>

or, use `reduce(vcat, ...)` if you want to work on the vector-of-vectors `x`:

```julia
a = [1,2,3,4,6]
b = [3,4,5,20]
c = [8,4,5,20]
d = [8,1,90,40]
x = [a,b,c,d,a]

```

```julia
julia> f = reduce(vcat, x)
22-element Vector{Int64}:
  1
  2
  3
  ⋮
  3
  4
  6

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [July 13, 2022, 4:48pm UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/4 "2022-07-13T16:48:23Z")

</div>

if you don’t necessarily have to use vcat

```julia
append!(f, x...)

```

instead if you want to use vcat 😀

```julia
vcat(x...)

```

```julia
[a;b;c;d;a]

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 13, 2022, 8:41pm UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/5 "2022-07-13T20:41:39Z")

</div>

Splatting can have quite unpredictable performance. In general, `reduce(vcat, x)`

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [July 13, 2022, 9:53pm UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/6 "2022-07-13T21:53:02Z")

</div>

> [@DNF](#):
>
> reduce(vcat, x)

How could we write our own Julia loop competitively?  
An attempt:

```julia
function vcat2(x::AbstractVector{<:AbstractVector})
    y = Array{eltype(x[begin])}(undef,sum(length,x))
    i = 1
    for u in x
        l = length(u)
        y[i:(i+l-1)] .= u
        i += l
    end
    return y
end

# Ex.1:
a, b, c, d = [1,2,3,4,6], [3,4,5,20], [8,4,5,20], [8,1,90,40]
x = [a,b,c,d,a]
@btime reduce(vcat, $x) # 80 ns (2 allocs: 336 bytes)
@btime vcat($x...) # 92 ns (1 alloc: 240 bytes)
@btime vcat2($x) # 85 ns (2 allocs: 336 bytes)

# Ex.2:
using Random
Random.seed!(123)
x = [rand(100) for _ in 1:100]
@btime reduce(vcat, $x) # 5.620 μs (3 allocs: 79 KiB)
@btime vcat($x...) # 5.740 μs (2 allocs: 78 KiB)
@btime vcat2($x) # 5.560 μs (2 allocs: 78 KiB)

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [July 13, 2022, 10:50pm UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/7 "2022-07-13T22:50:18Z")

</div>

```julia
julia> @btime vcat(x...);
  79.442 ns (1 allocation: 240 bytes)

julia> @btime reduce(vcat, x) ; 
  83.731 ns (2 allocations: 336 bytes)

julia> @btime vcat2(x) ;                    
  72.587 ns (2 allocations: 336 bytes)

```

---

<div class="post-metadata">

**Author:** ![Phuntsho](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phuntsho/32/46546_2.png) [@Phuntsho](https://discourse.julialang.org/u/Phuntsho)\
**Post date:** [July 14, 2022, 5:29am UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/8 "2022-07-14T05:29:19Z")

</div>

Thank you very much for the lovely answer. Out of all the good answers, I used

> reduce(vcat, x)

and it worked great until I had empty x. Empty x gave me the following error

```julia
ArgumentError: reducing over an empty collection is not allowed

```

Is there any way to resolve this issue? Thanks for the response.

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [July 14, 2022, 6:03am UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/9 "2022-07-14T06:03:16Z")

</div>

You need to specify an `init`

```julia
julia> reduce(vcat, Int[])
ERROR: ArgumentError: reducing over an empty collection is not allowed

julia> reduce(vcat, Int[], init=Int[])
Int64[]

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [July 14, 2022, 9:33am UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/10 "2022-07-14T09:33:41Z")

</div>

vcat with splatting does not suffer from this problem

```julia
a=rand(1:10, rand(1:10))
b=rand(1:10, rand(1:10))
c=rand(1:10, rand(1:10))
d=rand(1:10, rand(1:10))
e=rand(1:10, rand(1:10))
f=[]

x=[a,b,c,d,f,e]

vcat(x...)

y=[f,a,b,c,d,e,f]

Base.splat(vcat)(y)

```

even in terms of performance it does well

```julia
v=[rand(1:10, rand(0:10)) for _ in 1:100]

using BenchmarkTools
julia> @btime vcat(v...);
  873.684 ns (1 allocation: 4.06 KiB)

julia> @btime reduce(vcat, v, init=Int[]);
  19.600 μs (102 allocations: 206.09 KiB)

julia> vcat(v...)==reduce(vcat, v, init=Int[])
true

```

if you notice the number of allocations of `Base.splat(vcat)` is always 1 up to vectors with 256 elements. While that of `reduce(vcat)` is equal to the size of the vector v + 2

```julia

julia> v=[rand(1:10, rand(0:10)) for _ in 1:256]
256-element Vector{Vector{Int64}}:
 [8, 4, 8, 1, 1, 9]
 [4, 8, 6, 8, 10, 8, 6, 9, 4]
 [2, 3, 10, 5, 2]
 [6]
 [2, 3]
 [5, 4]
...
 [8, 4, 4, 10, 9, 1]
 [5]
 [8, 9]
 [3, 10, 9, 3, 3, 6, 9, 1, 9]
 []

julia> @btime vcat(v...);
  2.044 μs (1 allocation: 9.94 KiB)

julia> @btime reduce(vcat, v, init=Int[]);
  120.400 μs (258 allocations: 1.29 MiB)

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 14, 2022, 11:20am UTC](https://discourse.julialang.org/t/how-can-i-do-list-comprehension-for-vcat/84178/11 "2022-07-14T11:20:22Z")

</div>

> [@rocco\_sprmnt21](#):
>
> `@btime reduce(vcat, v, init=Int[]);`

For some reason, the `init` slows it down quite a bit:

```julia
julia> @btime reduce(vcat, $v, init=Int[]);
  23.151 μs (101 allocations: 210.23 KiB)

julia> @btime reduce(vcat, $v);
  962.444 ns (2 allocations: 5.12 KiB)

```

There is a related open issue for `mapreduce` ([#31137](https://github.com/JuliaLang/julia/issues/31137)) — it seems like we didn’t optimize a sufficiently low-level method of `reduce`.
