Created
December 6, 2011 01:43
-
-
Save willtownes/1436308 to your computer and use it in GitHub Desktop.
Faster way to list primes in Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def listprimes2(m): | |
'''another attempt to list all primes below m''' | |
values = range(m+1) #note that in this list the key and the value are the same. | |
primes = values[:] | |
primes[1] = 0 #1 doesn't count as a prime | |
for i in values: | |
if primes[i] == 0: | |
pass | |
else: | |
for j in values[i+1:]: | |
if primes[j]==0 or primes[j]%i != 0: | |
pass | |
else: | |
primes[j] = 0 | |
return primes | |
import time | |
tstart = time.time() | |
ans = sum(listprimes2(2000000)) | |
telapsed = time.time()-tstart |
It took about 37 seconds to execute. I know it's not perfect, but at least got the right answer.
thanks John!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It looks like you're creating two arrays populated with the values of their indices, then marking the non-prime entries as zero. You decide whether each number is prime or not by looking at every larger value. Unfortunately, you do this check too many times (see line 10,
for j in values[i+1:]:
). For example, you will check if the numberj = 500
is prime at least 499 times: wheni
is 1, wheni
is 2, etc.So you should instead devise a way that doesn't keep checking the same thing repeatedly.
Additionally, there are some obvious shortcuts you can take to reduce the running time.
Removing multiples of 2, 3, and 5 reduces the set of numbers you must check by about 70%, so you should instantly observe about a 3x speedup.
For a better approach to finding primes quickly, you should check out the Sieve of Eratosthenes, which is an extremely efficient way of finding small prime numbers (< 10 million to 20 million or so) quickly. In fact, if you kept following the bullets outlined above, and continued up to the largest prime that is less than
sqrt[2,000,000]
, that would actually be an equivalent algorithm to the SoE.