问题
Project Euler problem 7 says:
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the 10001st prime number?
Here's the code I've written in Python:
def primes(n):
primes = []
attempt = 3
while len(primes) < (n-1):
for i in range(len(primes)):
if attempt % primes[i] == 0:
attempt += 2
break
else:
primes.append(attempt)
print (primes)
return (primes)
While testing a number, if it finds that the number is divisible by one of the primes in the list, the for loop breaks, and starts again with a larger number. If it isn't divisible, it's added to the list of primes. This keeps going until the list is as large as desired (in this case 10000, and I've omitted 2 so the last member of the list is the 10001st prime)
The problem is that this is extremely SLOW. I've seen other solutions that can apparently solve this is seconds, if not less. What are some ways I could make this fun faster?
回答1:
These are optimizations problems, so you don't want to be printing every time you update the list. The other thing is don't use list at all because is not very memory efficient. You should use instead generators. Its very fast and you don't get to consume memory using lists. Below is a code for this purpose, watch how the yield keyword is being used in order to convert count_primes function into a generator.
def is_prime(num):
"""
Checks if a number is prime
"""
prime_counter = 1
for x in range(1, num):
if num % x == 0:
prime_counter += 1
if prime_counter > 2:
return False
return True
def count_primes():
"""
Counts primes until PRIMES_TO_COUNT
is reached
"""
PRIMES_TO_COUNT = 1000 # Modify this value
prime_counter_num = 0
start_point_num = 1
while True:
if is_prime(start_point_num):
if prime_counter_num == PRIMES_TO_COUNT:
yield start_point_num
print "This is the %dth prime number: %s" \
% (prime_counter_num, start_point_num)
break
prime_counter_num += 1
start_point_num += 1
if __name__ == '__main__':
for prime_number in count_primes():
print prime_number
Hope this helps you!. Python generators!
回答2:
Instead of checking for every odd number you can check for all numbers of the form 6n±1 because all primes are of that form.
来源:https://stackoverflow.com/questions/32333888/finding-the-10001st-prime-how-to-optimize