Python中的基本素数生成器
只是想得到一些关于我素数生成器的反馈。e、 它可以吗,它使用了很多资源等。它不使用库,它相当简单,反映了我目前的编程技能状态,所以不要像我想学的那样退缩Python中的基本素数生成器,python,Python,只是想得到一些关于我素数生成器的反馈。e、 它可以吗,它使用了很多资源等。它不使用库,它相当简单,反映了我目前的编程技能状态,所以不要像我想学的那样退缩 def prime_gen(n): primes = [2] a = 2 while a < n: counter = 0 for i in primes: if a % i == 0: counter += 1
def prime_gen(n):
primes = [2]
a = 2
while a < n:
counter = 0
for i in primes:
if a % i == 0:
counter += 1
if counter == 0:
primes.append(a)
else:
counter = 0
a = a + 1
print primes
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
def prime_gen(n):
素数=[2]
a=2
而a
有一些常见的优化:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
示例:
def prime(x):
if x in [0, 1]:
return False
if x == 2:
return True
for n in xrange(3, int(x ** 0.5 + 1)):
if x % n == 0:
return False
return True
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
- 覆盖基本情况
- 只迭代到n的平方根
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
我发现用Python编写的一个更有效的算法可以在下面的问答(使用筛子)中找到:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
我自己对筛选算法的改编:
from itertools import islice
def primes():
if hasattr(primes, "D"):
D = primes.D
else:
primes.D = D = {}
def sieve():
q = 2
while True:
if q not in D:
yield q
D[q * q] = [q]
else:
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 1
return sieve()
print list(islice(primes(), 0, 1000000))
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
在我的硬件上,我可以非常快地生成第一个一百万个素数(考虑到这是用Python编写的):
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
这是我不久前写的一个非常高效的素数生成器,它使用:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
#/usr/bin/env python2.7
def primeslt(n):
“”“查找所有小于n的素数”“”
如果n<3:
返回[]
A=[True]*n
A[0],A[1]=假,假
对于范围(2,int(n**0.5)+1)内的i:
如果A[i]:
j=i**2
而j
维基百科的文章(链接在上面)解释了它是如何比我更好地工作的,因此我建议您阅读。以下是根据C版本生成素数的标准方法:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
def prime_gen(n):
素数=[2]
#从3开始,因为2已经在列表中
下一次时间=3
当nexttime 虽然primes[i]我对参数为负时可以使用的第一个代码进行了一些优化:
def is_prime(x):
if x <=1:
return False
else:
for n in xrange(2, int(x ** 0.5 + 1)):
if x % n == 0:
return False
return True
print is_prime(-3)
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
def为素数(x):
如果x是Python,通常最好返回一个生成器,该生成器将返回一个无限素数序列,而不是一个列表
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
ActiveState有一个旧的埃拉托斯坦的列表
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
下面是其中一个更新到Python 2.7的版本,使用了一个step参数,在编写原始配方时,该参数不存在:
import itertools as it
def sieve():
""" Generate an infinite sequence of prime numbers.
"""
yield 2
D = {}
for q in it.count(3, 2): # start at 3 and step by odds
p = D.pop(q, 0)
if p:
x = q + p
while x in D: x += p
D[x] = p # new composite found. Mark that
else:
yield q # q is a new prime since no composite was found
D[q*q] = 2*q
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
因为它是一个生成器,所以它比生成整个列表的内存效率要高得多。由于它定位于复合,因此计算效率也很高
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
运行以下命令:
>>> g=sieve()
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
然后,每个后续调用返回下一个素数:
>>> next(g)
2
>>> next(g)
3
# etc
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
然后,您可以使用islice获得边界之间的列表(即,从第一个质数到X+Y质数的第X个质数…):
>>> tgt=0
>>> tgt, list(it.islice(sieve(), tgt, tgt+10))
(0, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29])
>>> tgt=1000000
>>> tgt, list(it.islice(sieve(), tgt, tgt+10))
(1000000, [15485867, 15485917, 15485927, 15485933, 15485941, 15485959, 15485989, 15485993, 15486013, 15486041])
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
获取第100个素数:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
获取质数直到100
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
import itertools
n=100
x = (i for i in xrange(1,n) if all([i%d for d in xrange(2,i)]))
for n in x:
print n
您可以从以下内容开始:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
def prime_gen(n):
primes = [2]
a = 2
while a < n:
counter = 0
for i in primes:
if a % i == 0:
counter += 1
if counter == 0:
primes.append(a)
else:
counter = 0
a = a + 1
print primes
这是一些基本的重构,应该会自动从您的手指中流出
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
然后测试重构后的代码,查看是否存在错误,并进行修复:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
def prime_gen(n):
primes = [2]
for a in range(3,n):
sqrta = sqrt(a+1)
isPrime = True
for i in primes:
if i >= sqrta:
break
if a % i == 0:
isPrime = False
break
if(isPrime):
primes.append(a)
return primes
最后,您将摆脱iPrime标志:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
def prime_gen(n):
primes = [2]
for a in range(3,n):
sqrta = sqrt(a+1)
for i in primes:
if i >= sqrta:
primes.append(a)
break
if a % i == 0:
break
return primes
现在你相信你完成了。然后突然,你的一位朋友指出,对于a
,甚至你也在无缘无故地检查i>=sqrta
。(类似地,对于a mod 3==0
numbers,分支预测也有帮助。)
您的朋友建议您在执行以下操作之前检查a%i==0
:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
def prime_gen(n):
primes = [2]
for a in range(3,n):
sqrta = sqrt(a+1)
for i in primes:
if a % i == 0:
break
if i >= sqrta:
primes.append(a)
break
return primes
现在你完成了,感谢你聪明的朋友 您也可以通过这种方式获得python字典中的素数
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
def is_prime(a):
count = 0
counts = 0
k = dict()
for i in range(2, a - 1):
k[count] = a % i
count += 1
for j in range(len(k)):
if k[j] == 0:
counts += 1
if counts == 0:
return True
else:
return False
def find_prime(f, g):
prime = dict()
count = 0
for i in range(int(f), int(g)):
if is_prime(i) is True:
prime[count] = i
count += 1
return prime
a = find_prime(20,110)
print(a)
{0: 23, 1: 29, 2: 31, 3: 37, 4: 41, 5: 43, 6: 47, 7: 53, 8: 59, 9: 61, 10: 67, 11:
71, 12: 73, 13: 79, 14: 83, 15: 89, 16: 97, 17: 101, 18: 103, 19: 107, 20: 109}
您可以使用pythonyield语句一次生成一个项。不是一次获取所有项,而是迭代生成器,一次获取一项。这将最小化您的资源
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
这里有一个例子:
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
from math import sqrt
from typing import Generator
def gen(num: int) -> Generator[int, None, None]:
if 2 <= num:
yield 2
yield from (
i
for i in range(3, num + 1, 2)
if all(i % x != 0 for x in range(3, int(sqrt(i) + 1)))
)
for x in gen(100):
print(x, end=", ")
我对jimifiki提出的解决方案进行了改进
import itertools
n=100
x = (i for i in itertools.count(1) if all([i%d for d in xrange(2,i)]))
print list(itertools.islice(x,n-1,n))[0]
import math #for finding the sqare root of the candidate number
def primes(n):
test = [3] #list of primes new candidates are tested against
found = [5] #list of found primes, which are not being tested against
c = 5 #candidate number, starting at five
while c < n: #upper bound, largest candidate will be this or 1 bigger
p = True #notes the possibility of c to be prime
c += 2 #increase candidate by 2, avoiding all even numbers
for a in test: #for each item in test
if c % a == 0: #check if candidate is divisible
p = False #since divisible cannot be prime
break #since divisible no need to continue checking
if p: #true only if not divisible
if found[0] > math.sqrt(c): #is samallest in found > sqrt of c
found.append(c) #if so c is a prime, add it to the list
else: #if not, it's equal and we need to start checking for it
test.append(found.pop(0)) #move pos 0 of found to last in test
return([2] + test + found) #after reaching limit returns 2 and both lists
import math#用于查找候选编号的sqare根
def素数(n):
test=[3]#对新候选人进行测试的素数列表
found=[5]#未针对其进行测试的已找到素数列表
c=5#候选人编号,从5开始
当cmath.sqrt(c):#是c的find>sqrt中的samallest吗
找到。追加(c)#如果c是素数,则将其添加到列表中
否则:#如果不是,它是相等的,我们需要开始检查它
test.append(find.pop(0))#将find的位置0移动到测试中的最后一个位置
返回([2]+测试+发现)#达到极限后返回2和两个列表
最大的改进是不检查偶数,只检查不可整除的数的平方根,当数变大时,后者真的加起来了。我们不需要检查平方根的原因是,测试列表只包含小于平方根的数字。这是因为只有当我们得到第一个不可被测试中的任何数字整除的非素数时,我们才加上下一个数字。