我正在寻找与python中的more_itertools.consecutive_groups行为相同的朱莉娅替代品。
我想出了一个简单的实现,但是速度是这里的问题,我不确定代码是否经过充分优化。
function consecutive_groups(array)
groups = eltype(array)[]
j = 0
for i=1:length(array)-1
if array[i]+1 != array[i+1]
push!(groups, array[j+1:i])
j = i
end
end
push!(groups, array[j+1:end])
return groups
end
您的实现已经相当快了。如果您知道连续的组将很大,那么您可能只想增加索引而不是 pushing
每个元素:
function consecutive_groups_2(v)
n = length(v)
groups = Vector{Vector{eltype(v)}}()
i = j = 1
while i <= n && j <= n
j = i
while j < n && v[j] + 1 == v[j + 1]
j += 1
end
push!(groups,v[i:j])
i = j + 1
end
return groups
end
在大型团体中,这大约快33%:
julia> x = collect(1:100000);
julia> @btime consecutive_groups(x)
165.939 μs (4 allocations: 781.45 KiB)
1-element Array{Array{Int64,1},1}:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 … 99991, 99992, 99993, 99994, 99995, 99996, 99997, 99998, 99999, 100000]
julia> @btime consecutive_groups_2(x)
114.830 μs (4 allocations: 781.45 KiB)
1-element Array{Array{Int64,1},1}:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 … 99991, 99992, 99993, 99994, 99995, 99996, 99997, 99998, 99999, 100000]
作为一个小小的评论,将其创建
groups
为函数顶部的本地vairable并在将第一个组像这样推送给它时实例化它会更通用groups = [v[i:j]]
。原因是您不能确定v[i:j]
生成一个Vector
,因为自定义AbstractArray
在被索引时可能会返回其他内容(例如,稀疏向量返回稀疏向量)。或者
groups = Vector{typeof(v[1:0])}()
。