arrays – Julia中随机输出的Array Comprehension

This question is an extension if one I asked earlier today.基本上,我试图在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 )

[单行被分成三行,因为它有点长;)]

由于缺少f,要测试此版本使用rand复制粘贴此版本:

(r=ones(0); any(i->(v=rand(); v>0.5 ? (push!(r,v); false) : true), 1:10); r)

它的基准测试比凤阳的功能慢了约10%.聪明的一点是利用任何短路实现.

附录:这里概括一下凤阳的一个版本需要抽象出这个问题的答案:

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

现在,我们可以实现上面的答案(用joker作为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

如果Julia推断f的返回类型,collectwhilecond也是类型稳定的.

编辑:使用@ 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
相关文章
相关标签/搜索