patternpythonMinor
Project Euler: primes in Python
Viewed 0 times
pythonprojecteulerprimes
Problem
This is a Python module I have just finished writing which I plan to use at Project Euler. Please let me know how I have done and what I could do to improve it.
# This constant is more or less an overestimate for the range in which
# n primes exist. Generally 100 primes exist well within 100 * CONST numbers.
CONST = 20
def primeEval(limit):
''' This function yields primes using the
Sieve of Eratosthenes.
'''
if limit:
opRange = [True] * limit
opRange[0] = opRange[1] = False
for (ind, primeCheck) in enumerate(opRange):
if primeCheck:
yield ind
for i in range(ind*ind, limit, ind):
opRange[i] = False
def listToNthPrime(termin):
''' Returns a list of primes up to the nth
prime.
'''
primeList = []
for i in primeEval(termin * CONST):
primeList.append(i)
if len(primeList) >= termin:
break
return primeList
def nthPrime(termin):
''' Returns the value of the nth prime.
'''
primeList = []
for i in primeEval(termin * CONST):
primeList.append(i)
if len(primeList) >= termin:
break
return primeList[-1]
def listToN(termin):
''' Returns a list of primes up to the
number termin.
'''
return list(primeEval(termin))
def lastToN(termin):
''' Returns the prime which is both less than n
and nearest to n.
'''
return list(primeEval(termin))[-1]Solution
# This constant is more or less an overestimate for the range in which
# n primes exist. Generally 100 primes exist well within 100 * CONST numbers.
CONST = 20
def primeEval(limit):Python convention says that functions should named lowercase_with_underscores
''' This function yields primes using the
Sieve of Eratosthenes.
'''
if limit:What is this for? You could be trying to avoid erroring out when limit=0, but it seems to me that you still error at for limit=1.
opRange = [True] * limitAs with functions, lowercase_with_underscore
opRange[0] = opRange[1] = False
for (ind, primeCheck) in enumerate(opRange):You don't need the parens around
ind, primeCheckif primeCheck:
yield ind
for i in range(ind*ind, limit, ind):
opRange[i] = False
def listToNthPrime(termin):
''' Returns a list of primes up to the nth
prime.
'''
primeList = []
for i in primeEval(termin * CONST):
primeList.append(i)
if len(primeList) >= termin:
break
return primeListYou are actually probably losing out by attempting to stop the generator once you pass the number you wanted. You could write this as:
return list(primeEval(termin * CONST))[:termin]Chances are that you gain more by having the loop be in the loop function than you gain by stopping early.
def nthPrime(termin):
''' Returns the value of the nth prime.
'''
primeList = []
for i in primeEval(termin * CONST):
primeList.append(i)
if len(primeList) >= termin:
break
return primeList[-1]
def listToN(termin):
''' Returns a list of primes up to the
number termin.
'''
return list(primeEval(termin))
def lastToN(termin):
''' Returns the prime which is both less than n
and nearest to n.
'''
return list(primeEval(termin))[-1]All of your functions will recalculate all the primes. For any sort of practical use you'll want to avoid that and keep the primes you've calculated.
Code Snippets
# This constant is more or less an overestimate for the range in which
# n primes exist. Generally 100 primes exist well within 100 * CONST numbers.
CONST = 20
def primeEval(limit):''' This function yields primes using the
Sieve of Eratosthenes.
'''
if limit:opRange = [True] * limitopRange[0] = opRange[1] = False
for (ind, primeCheck) in enumerate(opRange):if primeCheck:
yield ind
for i in range(ind*ind, limit, ind):
opRange[i] = False
def listToNthPrime(termin):
''' Returns a list of primes up to the nth
prime.
'''
primeList = []
for i in primeEval(termin * CONST):
primeList.append(i)
if len(primeList) >= termin:
break
return primeListContext
StackExchange Code Review Q#21659, answer score: 2
Revisions (0)
No revisions yet.