推广 热搜: page  考试  小红  红书  数据  论文  数据分析  关键词  哪些  搜索 

python素数生成器_Python中的简单Prime生成器

   日期:2025-01-02     移动:https://sicmodule.kub2b.com/mobile/quote/18009.html

有人可以告诉我这段代码在做什么吗? 无论如何,它只是打印"计数"。 我只想要一个非常简单的素数生成器(没什么花样)。

1

2

3

4

5

6

7

8

9

10

11

12

13import 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

你可以发表一些输出吗

它不终止吗? 毫不奇怪的是其中带有" while = 1"。 它根本不产生任何输出吗? 它会产生非素数吗? 太慢了吗? 不是C#吗? 问题是什么

如果这不是家庭作业,则可能需要研究Eratosthenes筛网:en.wikipedia.org/wiki/Sieve_of_Eratosthenes

我第二个CTT评论。 即使不是那么容易编码,也将同样容易。

有关Eratosthenes筛网的简单实现的信息,请参见:stackoverflow.com/questions/2068372/

有一些问题

当计数不除以x时,为什么要打印计数?这并不意味着它是素数,仅意味着该特定x不会将其除

continue移至下一个循环迭代-但您确实想使用break停止它

这是您的代码,其中包含一些修复程序,它仅输出质数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17import 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

有关更有效的质子生成,请参见其他人建议的戊二烯筛。这是一个不错的,经过优化的实现,带有很多注释

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37# 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

请注意,它返回一个生成器。

这个筛子非常简洁。它从哪里来的

那是筛子的一个非常好的实施。我以前从未见过它适用于无限范围,但回顾起来很明显。

字典操作非常耗时,如果您有足够的内存,则最好将所有数字保存在内存中,而不要使用字典来动态添加和删除元素。

@xiao我认为"运行中"的时间平均是恒定的,最糟糕的是线性

@yatisagade,嘿,python中的字典实现基于动态的集合,该集合不是laverage常量。它应该是log(n)。

@xiao看看:wiki.python.org/moin/TimeComplexity

要查看此作品,请在people.csail.mit.edu/pgbovine/python/tutor.html#mode=edit上进行尝试

如果您想查看此代码的来源,请参阅此线程code.activestate.com/recipes/117119-sieve-of-eratosthenes,并进行一些改进(在我的测试中为4倍)

确实应该推迟将值添加到dict中,直到在输入中看到它们的平方为止,如在stackoverflow.com/a/10733621/849891中。这大大降低了内存消耗,并改善了增长顺序。 cf.测试条目和相关讨论。

所以等等,如何使用呢

@FerdinandoRandisi:它返回一个生成器

直到现在都没见过。

这种动态筛子非常酷。为了进行校准,使其能够像这样运行无限发生器,使其比常规静态筛网慢3倍左右,后者将筛网预先填充到sqrt(max_prime)。

而推迟版本的Will Ness链接到一个简单的静态筛网所需的时间约为0.8。

1

2

3

4

5

6

7

8

9

10

11

12

13def 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的质数。

我本来可以用Eratosthenes的筛子,但是你说

您想要非常简单的东西。 ;)

1不是质数。 2和3是质数,并且丢失。因此,这对于前三个数字已经不起作用。

@heikogerlach非常正确。我已经解决了这个问题。现在请投票给我:)

如果您一直使用数字,它将修改为0并返回false。

其他是不必要的。如果它是素数,则该函数将返回True,并且可能会使初学者感到困惑。

如果将for x in range(2, num)更改为for x in range(2, math.trunc(math.sqrt(num)) + 1),则会得到相同的结果,但速度更快。

re功能强大

1

2

3

4

5

6

7

8

9

10import 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]

非常聪明!对那些感兴趣的人的解释。

1print [x for x in range(2,100) if not [t for t in range(2,x) if not x%t]]

这很简单,但效率不高。在典型的PC上,它需要几秒钟才能在range(10000)中工作

1

2

3

4

5

6

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

要测试数字是否为质数

1

2

3

4>>> 541 in primes(541)

True

>>> 543 in primes(543)

False

这是一个简单的(Python 2.6.2)解决方案...与OP的原始请求(现在已经六个月大)保持一致;并且应该是任何"编程101"课程中的一个完全可接受的解决方案。

1

2

3

4

5

6

7

8

9

10

11

12import 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等的倍数来更有效地完成……请参见Eratosthenes筛(请参见上述eliben的实现),甚至是Atkin筛子,如果您感到特别勇敢和/或疯狂。

注意警告:我是python noob。请不要接受我所说的任何福音。

我认为最好是采用功能性方法

因此,我首先创建一个函数以找出数字是否为质数,然后根据需要在循环或其他位置使用它。

1

2

3

4

5def isprime(n):

for x in range(2,n):

if n%x == 0:

return False

return True

然后运行简单的列表推导或生成器表达式以获取素数列表

1[x for x in range(1,100) if isprime(x)]

这似乎是作业,所以我将给出提示而不是详细说明。如果我认为做错了,请指正。

当您看到一个偶数除数时,您可以很好地解决问题。

但是,即使您看到一个不除的数字,也要立即打印"计数"。例如,2并不能平均分为9。但这并不能使9成为质数。您可能要继续操作,直到确定范围内没有数字匹配为止。

(正如其他人回答的那样,筛子筛查是一种更有效的方法……只是试图帮助您理解为什么此特定代码没有按照您的意愿做)

如果要直接计算素数,该怎么办

1

2

3

4

5

6

7

8

9

10

11

12

13

14def 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

另一个简单示例,仅考虑奇数进行简单优化。一切都用惰性流完成(python生成器)。

用法:素数=列表(create_prime_iterator(1,30))

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22import 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

SymPy是用于符号数学的Python库。它提供了几种生成素数的功能。

1

2

3

4

5

6

7

8

9

10

11isprime(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.

这里有些例子。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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

这是Eratosthenes筛子的小巧版本,具有很好的复杂性(比对长度为n的数组排序要低)和矢量化。

1

2

3

4

5

6

7

8import 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]

时间

1

2

3

4

5

6

7

8

9

10

11

12

13

14import 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

1

2

3

4

5

6

7

8

9

10

11def 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

我们真的需要测试101除以97,以找出101是否为质数吗

使用生成器

1

2

3

4

5

6def 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

用法

1

2for i in primes(10):

print(i)

2, 3, 5, 7

继续语句看起来不对。

您想从2开始,因为2是第一个质数。

您可以编写" while True"来获得无限循环。

1

2

3

4

5

6

7

8

9

10def 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

您可以以相当优雅的方式使用列表推导来创建素数列表。从这里拍摄

1

2

3

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

这是我所拥有的

1

2

3

4

5

6

7

8

9

10

11

12

13

14def 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

对于大数来说,这是非常快的,因为它只针对数字的除数来检查已经存在的质数。

现在,如果要生成素数列表,可以执行以下操作

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19# 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

为了提高效率,可能需要在此处使用发电机。

仅供参考,而不是说

1

2

3one = 1

while one == 1:

# do stuff

您可以简单地说

1

2while 1:

#do stuff

如果要查找范围内的所有素数,可以执行以下操作

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20def 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 <=和您的数字作为范围。

输出

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

您需要确保所有可能的除数不均分您要检查的数字。在这种情况下,只要可能的除数之一没有均匀地除以该数字,您就可以随时打印要检查的数字。

另外,您也不想使用continue语句,因为当您发现数字不是质数时,continue只会使它检查下一个可能的除数。

与user107745类似,但使用'all'而不是双重否定(更具可读性,但我认为性能相同)

1

2import math

[x for x in xrange(2,10000) if all(x%t for t in xrange(2,int(math.sqrt(x))+1))]

基本上在(2,100)范围内的x上进行迭代,并对范围(2,x)中的所有t只选择那些不具有mod == 0的那些

另一种方法可能是在填充素数时

1

2

3

4

5

6

7

8

9

10

11

12primes = 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))

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30import 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

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

对我而言,以下解决方案看起来很简单且易于遵循。

1

2

3

4

5

6

7

8

9

10

11

12import 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

is_prime(121)==是,但121不是素数。

本文地址:https://sicmodule.kub2b.com/quote/18009.html     企库往 https://sicmodule.kub2b.com/ , 查看更多

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


0相关评论
相关最新动态
推荐最新动态
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号