题
有人可以告诉我这段代码做错了什么吗?无论如何,它只是打印“计数”。我只想要一个非常简单的素数生成器(没什么花哨的)。
import math
def main():
count = 3
one = 1
while one == 1:
for x in range(2, int(math.sqrt(count) + 1)):
if count % x == 0:
continue
if count % x != 0:
print count
count += 1
解决方案
有一些问题:
- 为什么在未除以 x 时打印出 count ?这并不意味着它是素数,它只是意味着这个特定的 x 不能整除它
continue
移动到下一个循环迭代 - 但你真的想使用停止它break
这是经过一些修复的代码,它仅打印出素数:
import math
def main():
count = 3
while True:
isprime = True
for x in range(2, int(math.sqrt(count) + 1)):
if count % x == 0:
isprime = False
break
if isprime:
print count
count += 1
对于更有效的素数生成,请参阅埃拉斯托泰尼筛法,正如其他人建议的那样。这是一个很好的、优化的实现,有很多评论:
# Sieve of Eratosthenes
# Code by David Eppstein, UC Irvine, 28 Feb 2002
# http://code.activestate.com/recipes/117119/
def gen_primes():
""" Generate an infinite sequence of prime numbers.
"""
# Maps composites to primes witnessing their compositeness.
# This is memory efficient, as the sieve is not "run forward"
# indefinitely, but only as long as required by the current
# number being tested.
#
D = {}
# The running integer that's checked for primeness
q = 2
while True:
if q not in D:
# q is a new prime.
# Yield it and mark its first multiple that isn't
# already marked in previous iterations
#
yield q
D[q * q] = [q]
else:
# q is composite. D[q] is the list of primes that
# divide it. Since we've reached q, we no longer
# need it in the map, but we'll mark the next
# multiples of its witnesses to prepare for larger
# numbers
#
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 1
请注意,它返回一个生成器。
其他提示
def is_prime(num):
"""Returns True if the number is prime
else False."""
if num == 0 or num == 1:
return False
for x in range(2, num):
if num % x == 0:
return False
else:
return True
>> filter(is_prime, range(1, 20))
[2, 3, 5, 7, 11, 13, 17, 19]
我们将得到所有20高达素数在列表中。 我可以使用埃拉托色尼的筛但你说 你想要的东西很简单。 ;)
print [x for x in range(2,100) if not [t for t in range(2,x) if not x%t]]
re是强大:
import re
def isprime(n):
return re.compile(r'^1?$|^(11+)\1+$').match('1' * n) is None
print [x for x in range(100) if isprime(x)]
###########Output#############
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
def primes(n): # simple Sieve of Eratosthenes
odds = range(3, n+1, 2)
sieve = set(sum([range(q*q, n+1, q+q) for q in odds],[]))
return [2] + [p for p in odds if p not in sieve]
>>> primes(50)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
要测试一个数是否为素数:
>>> 541 in primes(541)
True
>>> 543 in primes(543)
False
这是一个 简单的 (Python 2.6.2)解决方案...这符合OP最初的要求(现已六个月前);并且应该是任何“编程 101”课程中完全可以接受的解决方案......因此这篇文章。
import math
def isPrime(n):
for i in range(2, int(math.sqrt(n)+1)):
if n % i == 0:
return False;
return n>1;
print 2
for n in range(3, 50):
if isPrime(n):
print n
这种简单的“蛮力”方法对于现代 PC 上高达约 16,000 的数字来说“足够快”(在我的 2GHz 机器上大约需要 8 秒)。
显然,通过不重新计算每个偶数的素数,或者每个数字的 3、5、7 等的每个倍数,这可以更有效地完成......请参阅 埃拉托斯特尼筛法 (参见上面 eliben 的实现),甚至 阿特金筛 如果你感觉特别勇敢和/或疯狂。
买者自负:我是一个蟒蛇菜鸟。请不要把我说的任何话当作福音。
我认为最好采取功能性方法,
因此,我首先创建一个函数来确定该数字是否为素数,然后根据需要在循环或其他地方使用它。
def isprime(n):
for x in range(2,n):
if n%x == 0:
return False
return True
然后运行一个简单的列表理解或生成器表达式来获取素数列表,
[x for x in range(1,100) if isprime(x)]
这似乎功课-Y,所以我会给出提示,而不是一个详细的解释。纠正我,如果我错了假设
您要尽可能做得细如想逃出来,当你看到一个更除数。
但你要打印尽快“计数”你看连的一个的不将其分为数。 2,例如,不均匀地分成9.但是,这并不让9的黄金。您可能要继续下去,直到你确信的没有的范围内的比赛数量。
(正如其他人回答说,筛是一种更有效的方式去...只是想帮助你明白为什么这个特定的代码是没有做你想要的)
这个怎么样,如果你想直接计算素数:
def oprime(n):
counter = 0
b = 1
if n == 1:
print 2
while counter < n-1:
b = b + 2
for a in range(2,b):
if b % a == 0:
break
else:
counter = counter + 1
if counter == n-1:
print b
另一个简单的例子,具有只考虑奇数号码的简单优化。一切与懒惰流(蟒发电机)进行。
用法:素数=列表(create_prime_iterator(1,30))
import math
import itertools
def create_prime_iterator(rfrom, rto):
"""Create iterator of prime numbers in range [rfrom, rto]"""
prefix = [2] if rfrom < 3 and rto > 1 else [] # include 2 if it is in range separately as it is a "weird" case of even prime
odd_rfrom = 3 if rfrom < 3 else make_odd(rfrom) # make rfrom an odd number so that we can skip all even nubers when searching for primes, also skip 1 as a non prime odd number.
odd_numbers = (num for num in xrange(odd_rfrom, rto + 1, 2))
prime_generator = (num for num in odd_numbers if not has_odd_divisor(num))
return itertools.chain(prefix, prime_generator)
def has_odd_divisor(num):
"""Test whether number is evenly divisable by odd divisor."""
maxDivisor = int(math.sqrt(num))
for divisor in xrange(3, maxDivisor + 1, 2):
if num % divisor == 0:
return True
return False
def make_odd(number):
"""Make number odd by adding one to it if it was even, otherwise return it unchanged"""
return number | 1
下面是筛的具有两行的复杂性和量化(比排序长度为n的数组低级)一个numpy的版本埃拉托塞尼的。
import numpy as np
def generate_primes(n):
is_prime = np.ones(n+1,dtype=bool)
is_prime[0:2] = False
for i in range(int(n**0.5)+1):
if is_prime[i]:
is_prime[i*2::i]=False
return np.where(is_prime)[0]
时序:
import time
for i in range(2,10):
timer =time.time()
generate_primes(10**i)
print('n = 10^',i,' time =', round(time.time()-timer,6))
>> n = 10^ 2 time = 5.6e-05
>> n = 10^ 3 time = 6.4e-05
>> n = 10^ 4 time = 0.000114
>> n = 10^ 5 time = 0.000593
>> n = 10^ 6 time = 0.00467
>> n = 10^ 7 time = 0.177758
>> n = 10^ 8 time = 1.701312
>> n = 10^ 9 time = 19.322478
continue 语句看起来是错误的。
您想从 2 开始,因为 2 是第一个质数。
您可以编写“while True:”来获得无限循环。
您需要确保所有可能的除数不整除您检查的数量。在这种情况下,你会打印您检查任何时候只是可能的除数之一不平均分配数目。
另外你不想使用continue语句,因为继续只会导致它来检查下一个可能的除数,当你已经发现这个号码是不是素。
下面是我有:
def is_prime(num):
if num < 2: return False
elif num < 4: return True
elif not num % 2: return False
elif num < 9: return True
elif not num % 3: return False
else:
for n in range(5, int(math.sqrt(num) + 1), 6):
if not num % n:
return False
elif not num % (n + 2):
return False
return True
这是非常快的大的数字,因为它仅针对已经质数检查一批约数。
现在,如果你想生成素数的列表,你可以这样做:
# primes up to 'max'
def primes_max(max):
yield 2
for n in range(3, max, 2):
if is_prime(n):
yield n
# the first 'count' primes
def primes_count(count):
counter = 0
num = 3
yield 2
while counter < count:
if is_prime(num):
yield num
counter += 1
num += 2
使用发电机这里可能希望为了效率。
的仅供参考,而不是说和:
one = 1
while one == 1:
# do stuff
您可以简单地说:
while 1:
#do stuff
您可以创建一个使用列表理解在一个相当优雅的方式素数的列表。从这里采取:
>>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
>>> primes = [x for x in range(2, 50) if x not in noprimes]
>>> print primes
>>> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
def genPrimes():
primes = [] # primes generated so far
last = 1 # last number tried
while True:
last += 1
for p in primes:
if last % p == 0:
break
else:
primes.append(last)
yield last
要user107745类似,但使用“全部”,而不是双重否定(一点点的可读性,但我认为相同的性能):
import math
[x for x in xrange(2,10000) if all(x%t for t in xrange(2,int(math.sqrt(x))+1))]
基本上,它遍历的X中的(2,100)的范围并且只有那些不具有模== 0对所有的t在范围采摘(2,x)的
另一种方式是可能只是填充的素数,我们去:
primes = set()
def isPrime(x):
if x in primes:
return x
for i in primes:
if not x % i:
return None
else:
primes.add(x)
return x
filter(isPrime, range(2,10000))
def check_prime(x):
if (x < 2):
return 0
elif (x == 2):
return 1
t = range(x)
for i in t[2:]:
if (x % i == 0):
return 0
return 1
SymPy 是对于符号数学一个Python库。它提供了多种功能,以生成的素数。
isprime(n) # Test if n is a prime number (True) or not (False).
primerange(a, b) # Generate a list of all prime numbers in the range [a, b).
randprime(a, b) # Return a random prime number in the range [a, b).
primepi(n) # Return the number of prime numbers less than or equal to n.
prime(nth) # Return the nth prime, with the primes indexed as prime(1) = 2. The nth prime is approximately n*log(n) and can never be larger than 2**n.
prevprime(n, ith=1) # Return the largest prime smaller than n
nextprime(n) # Return the ith prime greater than n
sieve.primerange(a, b) # Generate all prime numbers in the range [a, b), implemented as a dynamically growing sieve of Eratosthenes.
下面是一些例子。
>>> import sympy
>>>
>>> sympy.isprime(5)
True
>>> list(sympy.primerange(0, 100))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> sympy.randprime(0, 100)
83
>>> sympy.randprime(0, 100)
41
>>> sympy.prime(3)
5
>>> sympy.prevprime(50)
47
>>> sympy.nextprime(50)
53
>>> list(sympy.sieve.primerange(0, 100))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
如果你想找到一个范围内的所有素数,你可以这样做:
def is_prime(num):
"""Returns True if the number is prime
else False."""
if num == 0 or num == 1:
return False
for x in range(2, num):
if num % x == 0:
return False
else:
return True
num = 0
itr = 0
tot = ''
while itr <= 100:
itr = itr + 1
num = num + 1
if is_prime(num) == True:
print(num)
tot = tot + ' ' + str(num)
print(tot)
只需添加while its <=
和你的范围编号。结果
OUTPUT:点击
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101
使用发电机:
def primes(num):
if 2 <= num:
yield 2
for i in range(3, num + 1, 2):
if all(i % x != 0 for x in range(3, int(math.sqrt(i) + 1))):
yield i
用法:
for i in primes(10):
print(i)
2,3,5,7
import time
maxnum=input("You want the prime number of 1 through....")
n=2
prime=[]
start=time.time()
while n<=maxnum:
d=2.0
pr=True
cntr=0
while d<n**.5:
if n%d==0:
pr=False
else:
break
d=d+1
if cntr==0:
prime.append(n)
#print n
n=n+1
print "Total time:",time.time()-start
对于我来说,下面的解决方案看起来很简单,易于遵循。
import math
def is_prime(num):
if num < 2:
return False
for i in range(2, int(math.sqrt(num) + 1)):
if num % i == 0:
return False
return True