Jos*_*ath 3 arrays random list-comprehension julia
这个问题是如果我今天刚才问的延伸.基本上,我试图在Julia中编写一个数组理解,调用一个f(x)
输出为随机数的函数.当达到小于0.5的随机数时,我希望它杀死该函数.我能够编写以下代码:
X = [f(i)for i in 1:1:100 if(j = f(i); j <0.5?false:j> 0.5)]
这个问题是,它调用了两个单独的实例f(x)
,并且因为f(x)
每次都是随机的,所以上面不会在正确的实例中杀死for循环.我试过了
X = [J = f(i)for i in 1:1:100 if(J <0.5?false:J> 0.5)]
作为尝试保存特定的随机数,但它告诉我J没有定义.有没有办法保存这个特定的随机数来执行我的数组理解?
坚持一线解决方案并受@TasosPapastylianou的启发,快速解决方案将是:
X = ( r=Vector{Float64}() ;
any(i->(v=f(i) ; v>0.5 ? ( push!(r,v) ; false) : true), 1:100)
; r )
Run Code Online (Sandbox Code Playgroud)
[单行被分成三行,因为它有点长;)]
由于f
缺少,要测试此版本,请使用以下版本粘贴此版本rand
:
(r=ones(0); any(i->(v=rand(); v>0.5 ? (push!(r,v); false) : true), 1:10); r)
Run Code Online (Sandbox Code Playgroud)
它的基准测试比凤阳的功能慢了约10%.聪明的一点是利用any
短路实现.
ADDENDUM:这里概括一下凤阳的一个版本takewhile
来抽象这个问题的答案:
collectwhilecond(f,cond,itr) = begin
r=Vector{typeof(f(first(itr)))}()
all(x->(y=f(x); cond(y) ? (push!(r,y);true):false),itr)
return r
end
Run Code Online (Sandbox Code Playgroud)
现在,我们可以实现上面的答案(用joker
as f
):
julia> joker(i) = 1.0 + 4*rand() - log(i)
julia> collectwhilecond(joker, x->x>=0.5, 1:100)
3-element Array{Float64,1}:
4.14222
3.42955
2.76387
Run Code Online (Sandbox Code Playgroud)
collectwhilecond
如果Julia推断出f
返回类型,那么它也是类型稳定的.
编辑:使用@ tim的推荐方法推断返回类型f
而不拉动元素,itr
并且不会产生不稳定的f
生成错误,新的collectwhilecond
是:
collectwhilecond(f,cond,itr) = begin
t = Base.promote_op(f,eltype(itr)) # unofficial and subject to change
r = Vector{t}()
all( x -> ( y=f(x) ; cond(y) ? (push!(r,y) ; true) : false), itr )
return r
end
Run Code Online (Sandbox Code Playgroud)
你要做的事实上是一个简单的filter
操作:
filter(x -> x >= 0.5, [f(i) for i in 1:10])
Run Code Online (Sandbox Code Playgroud)
这基本上是我们if
在v0.5之前在julia中的列表推导中实现该部件之前首先依赖的东西
编辑:正如丹指出的那样,你可能在保留所有元素之后直到第一个<0.5的元素,例如:
L = [f(i) for i in 1:10]; L[1 : findfirst(L.<0.5) - 1]
Run Code Online (Sandbox Code Playgroud)
但是,在这种情况下,正如其他人所指出的那样,你也可以选择正常的for循环.列表推导将始终首先处理整个列表,因此它不会更快.你可以使用一个生成器,但是你必须创建自己的特殊机制才能使它停在正确的状态(正如凤阳建议的那样takewhile
).
因此,为了回答评论中的问题,在这种情况下你能做的最快的事情是正常的for循环,它会适当地破坏.此外,它最好包含在函数中而不是全局计算,如果指定变量的类型,它将进一步加速.