#!/usr/bin/env python
import math import timeit
def primeConcise(limit):
return [2] + [x for x in xrange(3, limit, 2) if not [y for y in [2] + range(3,x,2) if x%y==0]]
def primeConciseOptimized(limit):
return [2] + [x for x in xrange(3, limit, 2) if not [y for y in [2] + range(3,int(math.sqrt(x)), 2) if x%y==0]]
Hmm, I didn't know that 9 and 15 were prime...
When I'm doing timings like this I usually check the output. You can write a *very* fast algorithm if correctness does not count :-)
Here is a version that gives correct results at least up to limit=50:
def primeConciseOptimized(limit):
return [2] + [x for x in xrange(3, limit, 2) if not [y for y in [2] + range(3,int(math.sqrt(x))+1, 2) if x%y==0]]
One reason your listPrimes() function is faster is that it short-circuits the test - as soon as a divisor is found for a candidate, no further testing is done. primeConciseOptimized() always tests all the candidate divisors.
In the spirit of useless optimizations of bad algorithms ;) I used itertools to make a short-circuiting version of primeConciseOptimized():
import itertools def no(seq, pred=bool): '''Returns True if pred(x) is False for every element in the iterable From the itertools recipes. ''' for elem in itertools.ifilter(pred, seq): return False return True
def primeConciseOptimized2(limit):
return [2] + [x for x in xrange(3, limit, 2) if no(xrange(3,int(math.sqrt(x))+1, 2), lambda y: x%y==0)]
Note I don't bother testing for divisibility by 2 since the candidates are all odd. This allows using xrange() instead of range() for a significant improvement.
My times: listPrimes 0.143752069048 primeConciseOptimized 0.586845814203 primeConciseOptimized2 0.391731351331
Kent
def isPrime(x, primeList): limit = int(math.sqrt(x)) for i in primeList: if x % i == 0: return False if i >= limit: break return True
def listPrimes(upperLimit): listOfPrimes = [2] for i in xrange(3, upperLimit, 2): if isPrime(i, listOfPrimes): listOfPrimes.append(i) return listOfPrimes
if __name__ == '__main__':
t1 = timeit.Timer('listPrimes(50000)', 'from __main__ import listPrimes')
t2 = timeit.Timer('primeConciseOptimized(50000)', 'from __main__ import primeConciseOptimized')
t3 = timeit.Timer('primeConcise(50000)', 'from __main__ import primeConcise')
print t1.timeit(1)
print t2.timeit(1)
print t3.timeit(1)
-- Max
maxnoel_fr at yahoo dot fr -- ICQ #85274019
"Look at you hacker... A pathetic creature of meat and bone, panting and sweating as you run through my corridors... How can you challenge a perfect, immortal machine?"
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor