2017-10-06 43 views
1

我需要將以下代碼轉換爲list-comprehension(單行)。但是,我無法這樣做。 該代碼計算最高輸入範圍A的素數。用lambda函數將循環轉換爲double並打破列表理解

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 

到目前爲止,我下面哪個不起作用。特別是for-loop內的break正在拋棄我。

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])) 

編輯
增加對問題的約束。 該代碼只能是一個語句,沒有evalexec。代碼長度不得超過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) 

輸出

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)