简体   繁体   中英

Can someone help me identify the error in the prime generator function I wrote

Can someone help me why I get certain numbers like "27" and "35" in my generator when I'm listing out the first 25 primes? I know there are more efficient methods like the Sieve of Erathosthenes, but I'm concerned about some bug within this code. Thank you!

def next_prime():
    num = 2
    while True:
        for i in range(1, num+1):
            if (i != 1) and (num % i == 0):
                # print(num, " is not prime")
                num += 1
        yield num
        num += 1

primes = next_prime()
[print(next(primes)) for i in range(25)]

Output below-- A few of the composite numbers are highlighted

3 5 7 11 13 17 19 23 27 29 31 35 37 41 43 47 53 59 61 67 71 73 79 83 87

You increment num in the for loop, but you can not simply do that, since then i is not reset to 1 , and hence you miss certain checks.

You thus should break , and then increment the num and let the loop check the next number. We can thus use a for - else to only yield a number if the loop was successful (ie did not reach a break statement).

Another problem that now will occur is that no number is prime anymore. This is because your range(1, num+1) includes num , and a number is always dividable by itself. The range should thus span between 1 (or better 2 ), and num (exclusive):

def next_prime():
    num = 2
    while True:
        for i in range(2, num):
            if num % i == 0:
                break
        else:
            yield num
        num += 1

The above is however not very efficient. We can make this way faster. For example all even numbers, except for two are not primes, we can thus rewrite this to:

def next_prime():
    
    
    while True:
        for i in range(2, num):
            if not num % i:
                break
        else:
            yield num
        num += 

We furthermore only need to check up to √n for a number n , since if n is dividable by a number a with a greater than the square root of n , then there exists a number b = n / a that is smaller than the square root:

from math import sqrt, ceil

def next_prime():
    yield 2
    num = 3
    while True:
        for i in range(, , 2):
            if not num % i:
                break
        else:
            yield num
        num += 2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM