34: Finding Primes Faster in Python

Finding prime numbers is a common challenge in programming, and optimizing the process can lead to significant improvements in efficiency. In this blog post, we will explore a more efficient approach to finding prime numbers by leveraging a list of previously found primes. This method will help reduce unnecessary calculations and improve the overall performance of our prime-finding function.

Introduction:

To tackle this challenge, we will maintain a list of prime numbers as we iterate through potential prime candidates. This list serves two purposes:

  1. It holds the prime numbers that we will eventually return.
  2. It helps us check for factors of the current number being tested.

Step-by-Step Solution

Let’s break down the steps involved in our optimized prime-finding function.

Initialize the List of Primes: Start with a list containing the number 2, which is the only even prime number.

				
					primes = [2]

				
			

Iterate Through Potential Primes: Loop through odd numbers starting from 3 up to the specified limit.

				
					def find_primes(limit):
    primes = [2]
    for num in range(3, limit + 1, 2):
        is_prime = True
        sqrt_num = int(num ** 0.5) + 1
        
        for prime in primes:
            if prime > sqrt_num:
                break
            if num % prime == 0:
                is_prime = False
                break
        
        if is_prime:
            primes.append(num)
    
    return primes

				
			
  • Check for Factors Efficiently: For each candidate number, check divisibility using only the primes in our list up to the square root of the candidate. This reduces the number of checks needed.

  • Append New Primes: If a candidate number is not divisible by any of the primes checked, it is a prime number and is appended to our list of primes.

  • Return the List of Primes: Finally, return the list of primes collected during the iteration.

Complete Code Example

Here is the complete function to find prime numbers up to a given limit:

				
					def find_primes(limit):
    primes = [2]
    
    for num in range(3, limit + 1, 2):
        is_prime = True
        sqrt_num = int(num ** 0.5) + 1
        
        for prime in primes:
            if prime > sqrt_num:
                break
            if num % prime == 0:
                is_prime = False
                break
        
        if is_prime:
            primes.append(num)
    
    return primes

# Example usage:
limit = 100
prime_numbers = find_primes(limit)
print(prime_numbers)

				
			

Explanation

  • Starting with 2: We begin our list with the number 2, the only even prime.
  • Looping through Odd Numbers: We only check odd numbers starting from 3 since even numbers greater than 2 are not prime.
  • Square Root Optimization: By calculating the square root of the candidate number once and storing it in a variable, we avoid recalculating it multiple times within the loop.
  • Efficient Factor Check: We check for factors using only the primes in our list, up to the square root of the candidate number. If no factors are found, the number is prime.

Conclusion

Optimizing the prime-finding process can significantly reduce computation time, especially for larger limits. By maintaining a list of previously found primes and using it to check for factors, we make our function more efficient. Remember to balance optimization with code readability to maintain the “Pythonic” way of writing clean and understandable code.