我在Julia中有以下代码行:
X=[(i,i^2) for i in 1:100 if i^2%5==0]
基本上,如果(i,i^2)
和i=1 to 100
的剩余部分为零,它会从i^2
返回元组5
的列表。我想要做的是,在数组理解中,如果i^2
变得大于1000
,则跳出for循环。但是,如果我实施
X=[(i,i^2) for i in 1:100 if i^2%5==0 else break end]
我收到错误:syntax: expected "]"
。
有没有办法轻松打破数组中的for循环?我试过在网上看,但没有出现。
答案 0 :(得分:6)
这是一个“假的”for-loop,所以你不能break
它。看看下面的降低代码:
julia> foo() = [(i,i^2) for i in 1:100 if i^2%5==0]
foo (generic function with 1 method)
julia> @code_lowered foo()
LambdaInfo template for foo() at REPL[0]:1
:(begin
nothing
#1 = $(Expr(:new, :(Main.##1#3)))
SSAValue(0) = #1
#2 = $(Expr(:new, :(Main.##2#4)))
SSAValue(1) = #2
SSAValue(2) = (Main.colon)(1,100)
SSAValue(3) = (Base.Filter)(SSAValue(1),SSAValue(2))
SSAValue(4) = (Base.Generator)(SSAValue(0),SSAValue(3))
return (Base.collect)(SSAValue(4))
end)
输出显示array comprehension
是通过Base.Generator
实现的,它将迭代器作为输入。它目前仅支持[if cond(x)::Bool]
“后卫”,因此无法在此处使用break
。
对于您的具体情况,解决方法是使用isqrt
:
julia> X=[(i,i^2) for i in 1:isqrt(1000) if i^2%5==0]
6-element Array{Tuple{Int64,Int64},1}:
(5,25)
(10,100)
(15,225)
(20,400)
(25,625)
(30,900)
答案 1 :(得分:5)
我不这么认为。你总是可以
tmp(i) = (j = i^2; j > 1000 ? false : j%5==0)
X=[(i,i^2) for i in 1:100 if tmp(i)]
答案 2 :(得分:4)
使用for
循环在Julia中被认为是惯用的,在这种情况下可能更具可读性。此外,它可能会更快。
具体做法是:
julia> using BenchmarkTools
julia> tmp(i) = (j = i^2; j > 1000 ? false : j%5==0)
julia> X1 = [(i,i^2) for i in 1:100 if tmp(i)];
julia> @btime [(i,i^2) for i in 1:100 if tmp(i)];
471.883 ns (7 allocations: 528 bytes)
julia> X2 = [(i,i^2) for i in 1:isqrt(1000) if i^2%5==0];
julia> @btime [(i,i^2) for i in 1:isqrt(1000) if i^2%5==0];
281.435 ns (7 allocations: 528 bytes)
julia> function goodsquares()
res = Vector{Tuple{Int,Int}}()
for i=1:100
if i^2%5==0 && i^2<=1000
push!(res,(i,i^2))
elseif i^2>1000
break
end
end
return res
end
julia> X3 = goodsquares();
julia> @btime goodsquares();
129.123 ns (3 allocations: 304 bytes)
因此,另外2倍的改进是无可忽视的,而长函数为照明评论提供了充足的空间。