2017-10-06 17 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)