4

Searching for python prime numbers generator, I found:

def primes(n): 
    if n==2: return [2]
    elif n<2: return []
    s=range(3,n+1,2)
    mroot = n ** 0.5
    half=(n+1)/2-1
    i=0
    m=3
    while m <= mroot:
        if s[i]:
            j=(m*m-3)/2
            s[j]=0
            while j<half:
                s[j]=0
                j+=m
        i=i+1
        m=2*i+3
    return [2]+[x for x in s if x]

print primes(13)
print primes(3000)

and also:

def get_primes(number):
    while True:
        if is_prime(number): #is_prime is defined somewhere else
            yield number
        number += 1

What's more efficient, return a list or the yield command? Why? Consider I'm looking for a very large amount of primes numbers, like first 1000 primes. By the way, the second code seems to be an infinite loop, how to stop it?

Thanks and sorry for so many questions.

Nacib Neme
  • 809
  • 1
  • 17
  • 25
  • 3
    The two methods are not comparable at all; one loops through all possible numbers and tests each one, the other goes about it far more efficiently by implementing a sieve. You are comparing apples and pears here. – Martijn Pieters Jun 30 '13 at 21:06

1 Answers1

4

It really depends on what you want to do with the list of primes.

First off, as Martijn pointed out, the first algorithm is a pretty clever prime sieve, and the second tests every prime number. If you're interested in fast prime number algorithms, I would look up a few different prime sieves to try to better understand the approach. The simplest is the Sieve of Eratosthenes.

Anyway, I don't think that was your question. You're really looking for the difference between a normal Python function and a generator. There are a lot of questions on SO and plenty of documentation that give a good explanation of what a generator is.

This showed up in the sidebar when I was looking at your question, and I imagine that it would be helpful. Or just search the docs for "generator".

The quick explanation is that your first function returns a list of primes up to n. Once you have that list, you can access any member of it when you want, call a function on the whole list, etc. The second approach is a generator. It doesn't return a list -- this returns an iterator that comes up with the next prime on demand. So if you need the primes one at a time, in order, perhaps to call a function on each one, an iterator might be good. If you need to access the primes on demand, this won't do, however.

If you're looking for the first prime that meets some criteria, a generator is good, because you don't have to specify a range. No reason to generate the first thousand primes if you only need the first 100.

For example:

for prime in get_primes(2):
    if meets_condition(prime):
        return prime

will be better than:

primeList = primes(1000)
for prime in primeList:
    if meets_condition(prime):
        return prime

If n is small, but not if n is anywhere close to 1000.

Gotta go, sorry. I'll expand and proofread this later. Look up generators and prime sieves!

If you're working on a projecteuler.com problem, I'm going to go ahead and guess that the sieve will work better.

Community
  • 1
  • 1
vroomfondel
  • 2,886
  • 1
  • 18
  • 31