Today, I wrote a short script for a prime sieve, and I am looking to improve on it. I am rather new to python and programming in general, and so I am wondering: what is a good way to reduce memory usage in a program where large lists of numbers are involved? Here is my example script:
def ES(n):
A = list(range(2, n+1))
for i in range(2, n+1):
for k in range(2, (n+i)//i):
A[i*k-2] = str(i*k)
A = [x for x in A if isinstance(x, int)]
return A
This script turns all composites in the list, A, into strings and then returns the list of remaining integers, which are all prime, yet it runs the A[i*k-2] = str(i*k) three times for the number 12, as it goes through all multiples of 2, then 3 and again for 6. With something like that happening, while storing such a large list, I hit a brick wall rather soon and it crashes. Any advice would be greatly appreciated! Thanks in advance.
EDIT: I don't know if this makes a difference, but I'm using Python 3.3
First, you're using a really weird, inefficient way to record whether something is composite. You don't need to store string representations of the numbers, or even the numbers themselves. You can just use a big list of booleans, where
prime[n]
is true ifn
is prime.Second, there's no reason to worry about wasting a bit of space at the beginning of the list if it simplifies indexing. It's tiny compared to the space taken by the rest of the list, let alone all the strings and ints and stuff you were using. It's like saving $3 on paint for your $300,000 car.
Third,
range
takes astep
parameter you can use to simplify your loops.