2017-05-21 6 views
3

루프를 들어 : i^25의 나머지가 0 인 경우 기본적으로, 그것은 i=1 to 100에서 튜플 (i,i^2)의 목록을 반환죽이고 내가 줄리아 코드의 다음 줄이 줄리아 배열 이해

X=[(i,i^2) for i in 1:100 if i^2%5==0] 

합니다. 배열의 이해에서 i^21000보다 커지면 for 루프를 빠져 나가고 싶습니다. 그러나 구현하는 경우

X=[(i,i^2) for i in 1:100 if i^2%5==0 else break end] 

나는 오류 : syntax: expected "]"가 표시됩니다.

배열 내부에서 for 루프를 쉽게 벗어날 수있는 방법이 있습니까? 나는 온라인으로 보려고했지만 아무 것도 나오지 않았다.

답변

5

나는 그렇게 생각하지 않는다. 당신은 언제나

tmp(i) = (j = i^2; j > 1000 ? false : j%5==0) 
X=[(i,i^2) for i in 1:100 if tmp(i)] 
+0

나중에 질문이 있습니다 http://stackoverflow.com/questions/44101965/array-comprehension-with-a-random-output-in-julia (편집 : 더 최근 답변) 여기에 의견이있었습니다 루프를 작성하는 것이 좋습니다. 나는 이것에 동의한다. 이것은 단지 제기 된 질문에 대답하려는 시도 일 뿐이다. –

5

그것은을위한 루프는 "가짜"입니다 수 있도록하지 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] "guard"만 지원하므로 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) 
3

줄리아에 관용적 간주됩니다 for 루프를 사용하고이 경우에 더 많은 읽을 수 있습니다. 또한 더 빠를 수도 있습니다. 특히

:

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) 

그래서 다른 배 개선이 무시 아무것도없고 긴 기능 댓글을 조명하기위한 충분한 공간을 제공합니다.

+1

조기 종료 외에도 루프를 작성하는 데있어 본질적으로 빠르지 않아야합니다. 이것이 바로 이해법 코드의 의미입니다. 휴식을 허용하거나 이해하는 것이 가능할 수 있지만 의미는 약간 분명하지 않습니다. 다른 언어 (예 : 파이썬)에서 허용합니까? – StefanKarpinski

+0

@StefanKarpinski'isqrt' 버전은 루프 버전만큼 빨리 끝나며 여전히 2 배 더 느립니다. 왜 그런가요? (추측 : 뿌리를 내리는 것은 천천히) –

+0

Re : 마지막 코멘트, isqrt는 범인이 아닙니다. 상한값을 손으로 코딩하고 더 많은 항목 (최대 10,000 개)을 실행하는 것은'goodsquares'에 찬성하여 여전히 2 배의 요소를 가지고 있습니다 –