Recently came across this piece of code online:
nonprime = [j for i in range(2, 8) for j in range(i*2, 50, i)]
The above code seems to be calculating all the non primes below 50,but I am not getting the logic. I studied list comprehensions in python and observed it uses filter to filter based on conditions, but all I cannot understand how two for loops are calculating these non primes.
This list comprehension does the same as these two nested for loops:
nonprime=[]
for i in range(2,8):
for j in range(i*2, 50,i):
nonprime.append(j)
So in the outer loop, i
is just increased by one in every iteration, and takes on the values i=2,3,4,5,6,7.
The inner for loop over j
depends on the outer loop. It starts at 2*i
and j
is increased by i
in each iteration.
So for ì=2
, the inner loop starts at j=4
and j
takes on the values j=4,6,8,...,48
.
Then ì
is increased to 3 in the outer loop and j
takes on the values 6,9,12,...48
Notice that the nonprime
list does not create unique elements, since for example the 6 appears more than once.
As Bakuriu rightfully points out, this method makes use of the Sieve of Eratosthenes
The key to this answer lies in Mathematics:
If a number n>1 is not prime, then it has a prime factor <= sqr(n)
Now we are left to explain the logic. Note that sqrt(50) < 8
, which is the limit of the first range
.
We may rewrite the nested list comprehension as a regular loop. We can use set
instead of a list, which will have unnecessary repeated elements:
res = set()
for i in range(2, 8):
for j in range(i*2, 50, i):
res.add(j)
The outer loop iterates all i < sqrt(50)
.
The inner loop iterates, for each i
, all multiples of i
less than 50.
By the aforementioned Mathematical statement, we have all non-primes under 50. This is true because we are exhausting all prime factors <= sqrt(50).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With