我需要计算前五个素数。我想在列表理解中构建它时检查列表的长度。以下代码无效。
def checkPrime(n):
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
primes = []
primes = [x for x in range(2,30) if(checkPrime(x) and len(primes)<6) ]
print primes
输出:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
为什么len(primes)<6
无效。我怎样才能做到这一点?
答案 0 :(得分:5)
&#34; Pythonic&#34;方法是使用generator加上islice
函数:
from itertools import islice
def checkPrime(n):
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
def primes():
i = 2
while True:
if checkPrime(i):
yield i
i += 1
first_5 = list(islice(primes, 5))
这将创造一个无限的&#34;列表&#34;名为primes
,您可以使用多种方式使用列表,但它实际上只会计算您需要的值。
答案 1 :(得分:4)
使用itertools.islice
与filter
结合使您的计算变得懒惰。
from itertools import islice
def checkPrime(n):
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
primes = filter(checkPrime, range(2, 10**100))
list(islice(primes, 6)) # [2, 3, 5, 7, 11, 13]
答案 2 :(得分:3)
列表理解创建并返回新列表。在您的代码中,在列表理解中,len(primes)
将始终返回为零,因为在列表理解完成并返回新列表之前,列表的长度不会更新。
如果你必须使用列表理解 ,你可以创建一个生成器函数来返回下一个素数范围。在列表推导内调用生成器对象上的next()
(使用range
来限制所需值的计数)。
例如:
def checkPrime(n):
for i in range(2,int(n**0.5)+1):
if n%i==0:
return False
return True
# Generator function
def getPrimes(n):
for x in range(2, n):
if(checkPrime(x)):
yield x
# Create Generator object
primes_gen = getPrimes(30)
# List comprehension to get primes
primes = [next(primes_gen) for _ in range(5)]
# ^ ^ required count of prime numbers in list
# ^ to get next prime number
primes
保留的最终值为:
>>> primes
[2, 3, 5, 7, 11]
正如robbrit's answer中所述, Pythonic实现此目的的方法是使用itertools.islice
(但它不是您所要求的列表理解) :
>>> from itertools import islice
# v type-casting it to list for displaying the list,
# v as `islice` also returns a generator object
>>> list(islice(getPrimes(30), 5))
[2, 3, 5, 7, 11] # ^ generator function from my older example