2017-10-06 16 views
1

私はlist-comprehension(1つのライナー)に変換する必要があるコードに従いました。しかし、私はそうすることができません。 コードでは、入力範囲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])) 

EDIT
問題の制約を追加します。 コードはevalまたはexecを除いた1つのステートメントのみです。コードの長さは最大160文字でなければなりません。

+4

なぜ?私はこのリスト理解を解読しなければならない人を哀れに思う。 –

+0

最初はなぜそれをリストの理解に変換したいのですか? –

+0

私が知っているのは、ライナーソリューションを1つしか受け付けないオンライン問題の一部です。 1つのライナーを提供する他の方法がない限り。 –

答えて

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

この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) 
関連する問題