2017-10-06 5 views
1

list-comprehension (한 라이너)으로 변환해야하는 코드를 따라했습니다. 그러나, 나는 그렇게 할 수 없다. 코드는 최대 입력 범위 A의 소수를 계산합니다.람다 함수를 사용하여 double for 루프를 변환하고 목록 이해로 전환

def sieve(A):  
    l = [] 
    f = lambda x : int(x**0.5) 
    for p in range(2,A+1):   
     for i in range(2, f(p) + 1): 
      if p % i == 0: 
       break 
     else: 
      l.append(p) 
    return l 

지금까지는 어떤 방식으로 작동하지 않습니다. 특히 break 내에서 for-loop 내게 던지고있다.

list(set([val for sublist in [[p for i in range(2, f(p) + 1) if p %i != 0 ] for p in range(2,A) ] for val in sublist])) 

편집
문제에 대한 제약 조건을 추가. 코드는 eval 또는 exec없이 하나의 명령문 일 수 있습니다. 코드 길이는 최대 160 자 여야합니다.

+4

이유는 무엇입니까? 나는이 목록 이해력을 해독하고 해독해야하는 사람을 불쌍히 여긴다. –

+0

왜 처음부터 목록 이해력으로 변환되기를 원하십니까? –

+0

저는 라이너 솔루션을 하나만 허용하는 온라인 문제의 일부입니다. 하나의 라이너를 제공하는 다른 방법이없는 한. –

답변

1
[p for p in range(2,A+1) if next((i for i in range(2, int(p**0.5) + 1) if (p % i) == 0),None)==None] 

코드 길이는 100 자입니다.
우리는 반복을 벗어나는 데 next()을 사용합니다.
설명

def sieve(A): 
    [p for p in range(2,A+1) if getFirstDiv(p)==None] 

def getFirstDiv(p): 
    next(divIter(p),None) 

def divIter(p): 
    return (i for i in range(2, int(p**0.5) + 1) if (p % i) == 0) 

OUTPUT

15 --> [2, 3, 5, 7, 11, 13] 
10 --> [2, 3, 5, 7] 
+0

아, 나는 다음에()를 놓치기 때문에 잘 알고 있습니다. 주어진 시간 제약 내에서 A = 10000 +에 대해서도 완벽하게 작동합니다. 고마워. –

1

이 하나 라이너는 그것을 할 것입니다 :

[r for r in [i*all([i if i%j!=0 else 0 for j in range(2,i)]) for i in range(2,x)] if r>0] 

당신은 단지 설정해야 x (최대 값).

참고 : 효율성은이 질문의 목적이 아니라고 생각하지만 특별히 효율적이지는 않습니다.

설명 (확장 번호) :

filtered = [] 
primes = [] 

for i in range(2,x): 
    # Check that all numbers up to i do not divide i 
    # I realise we only need to check up to int(sqrt(i)) 
    condition = all([i if i%j!=0 else 0 for j in range(2,i)]) 

    # Exploit Python's treatment of bool: number*True = number and number*False=0 
    filtered.append(i*condition) 


for r in filtered: 
    # Take out all the zeros 
    if r>0: 
     primes.append(r)