There is nothing wrong with the StopIteration
, indeed that is the expected behaviour for generators.
I would say this implementation is more pythonic (not necessarily more efficient):
def get_primes(n):
"""Generates prime numbers < n"""
return (x for x in xrange(2,n) if all(x % i for i in xrange(2,x)))
Pythonic to me means clear, concise, readable, and using the strengths of the language. While I can see your implementation is some sort of sieve, I only know that from prior experience with those kind of algorithms. The implementation above I can read directly as a straight-forward test of divisibility.
Note: there is a minor difference in the interface, your implementation would yield primes <= n whereas my implementation would yield primes < n. Obviously this can be changed easily and trivially (just change n to n+1 in the function body), but I feel it is more pythonic to generate primes up-to-but-not including n to be more consistent with the way, say, range()
builtin works.
EDIT: JUST FOR FUN
Here is a least pythonic implementation, and probably pretty inefficient too :)
def get_primes(n):
import re
return (x for x in xrange(2,n) if re.match(r'^1?$|^(11+?)\1+$', '1' * x) is None)
I call this the least pythonic because you would be scratching your head for some days to figure out how it works if you haven't seen this trick before!!