I am trying to create a vector using in-line for loop.
indices = [2,5,6,8]
[i:i+6; for i in indices]
which returns
4-element Vector{UnitRange{Int64}}:
2:8
5:11
6:12
8:14
How to create vector of values instead of ranges?
I am trying to create a vector using in-line for loop.
indices = [2,5,6,8]
[i:i+6; for i in indices]
which returns
4-element Vector{UnitRange{Int64}}:
2:8
5:11
6:12
8:14
How to create vector of values instead of ranges?
You mean like this?
julia> reduce(vcat, [i:i+6 for i in indices])
28-element Vector{Int64}:
2
3
4
5
6
7
8
5
6
(...)
Sorry actually you don’t even need the array comprehension as reduce
accepts a generator, so this will likely be more efficient:
reduce(vcat, i:i+6 for i in indices)
another way to —
vcat((:).(indices,indices.+6)...)
Something like this should work and may be faster yet:
[ i+j for j in 0:6 for i in indices ]
(not tested, I may get the index order wrong).
(But I guess reduce (vcat,…) does not allocate any intermediate either?)
I see:
julia> @btime reduce(vcat, i:i+6 for i in $indices)
156.910 ns (9 allocations: 880 bytes)
and
julia> @btime [ i+j for j in 0:6 for i in $indices ]
175.882 ns (4 allocations: 544 bytes)
(yours does get the indices wrong)
It also seems like the reduce
trick actually doesn’t help here?
julia> @btime vcat([i:i+6 for i in $indices]...)
136.101 ns (6 allocations: 544 bytes)
EDIT actually I only tried this because my subconscious reminded me that Frames was griping about this issue the other day:
matlab influence:
julia> ([indices...;;] .+ [0:6...])[:]
Just for completeness:
julia> inds = indices = [2,5,6,8]
4-element Vector{Int64}:
2
5
6
8
julia> @btime reduce(vcat, i:i+6 for i in $inds );
208.478 ns (9 allocations: 880 bytes)
julia> @btime [ i+j for i in $inds for j in 0:6 ];
240.907 ns (4 allocations: 544 bytes)
julia> function f(inds, range)
v = Int[]
for i in inds
for j in range
push!(v, i+j)
end
end
return v
end
f (generic function with 2 methods)
julia> @btime f($inds, 0:6);
199.283 ns (3 allocations: 480 bytes)
julia> function f2(inds, range)
v = Vector{Int}(undef, length(range)*length(inds))
ii = 0
for i in inds
for j in range
ii += 1
v[ii] = i + j
end
end
return v
end
f2 (generic function with 1 method)
julia> @btime f2($inds, 0:6);
47.373 ns (1 allocation: 288 bytes)
The only thing I don’t “like” is that f
is faster than the comprehension, which I thought would be lowered to the same thing.