Varun
Varun

Reputation: 1043

understanding range in python for loop

The program below is finding prime numbers in a given range. for the noprimes list comprehension part, why do we have 3 parameters in range?

noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
primes = [x for x in range(2, 50) if x not in noprimes]
print prime

and what is i doing there?

Upvotes: 3

Views: 42673

Answers (4)

Levon
Levon

Reputation: 143027

For range(), the basic idea is that it generates a sequence of items for you. See this as reference http://docs.python.org/library/functions.html#range :

 format: range([start], stop[, step])

In the meantime here is some basic explanation, easiest example:

 range(5)

will generate numbers in the range starting at 0 (default start value) and go up to but not including 5, by increments of 1 (default value), so

 In [1]: range(5)
 Out[1]: [0, 1, 2, 3, 4]

You can specify additional parameters to range, such as the starting value, the ending value and also the stepvalue. So range(startval, endval, stepval). Notice that endval is not included in the sequence that is generated.

 range(0, 5, 1)

is equivalent to

 range(5)

To generate all even numbers between 0 and 20 you could do for instance

 range(0, 21, 2)

Note that prior to Python 3 range generates a list and xrange generates the number sequence on demand.

In your specific code are using list comprehensions and range. It might be easier to understand the algorithm and the role of the for loops with range by eliminating the list comprehension temporarily to get a clearer idea. List comprehension is a powerful and efficient construct and should definitely be used if you plan on keeping the original code though.

#noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)]
noprimes = []
for i in range (2, 8):
   for j in range (i*2, 50, i):
      noprimes.append(j)

# primes = [x for x in range(2, 50) if x not in noprimes]
primes = []
for x in range(2, 50):
   if x not in noprimes:
      primes.append(x)

Upvotes: 5

Praveen Gollakota
Praveen Gollakota

Reputation: 38930

Basically you're stepping by i in non-primes to generate multiples of i (any multiple obviously a non-prime). i is in range(2,8) i.e. [2, 3, 4, 5, 6, 7] because for primes till 50 you only need to eliminate multiples of numbers until sqrt(50) which is 7 (approximately).

If a nested list comprehension is confusing, try breaking it down into steps for easier understanding.

>>> [j for i in [2] for j in range(i*2, 50, i)]
[4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]
>>> [j for i in [3] for j in range(i*2, 50, i)]
[6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48]

BTW, also look around online for better prime number algorithms. This one algorithmically very poor.

Upvotes: 1

WeaselFox
WeaselFox

Reputation: 7380

The three parameters of range were explained by ThiefMaster. about the code - code looks ok to me. The only problem seems to be the print prime line. maybe you should add

for prime in primes :
   print prime

Upvotes: 0

ThiefMaster
ThiefMaster

Reputation: 318468

See the docs:

range([start], stop[, step])

When comparing it to a for(..; ..; ..) loop e.g. in C the three arguments are used like this:

for(int i = start; i != stop; i += step)

There are also good examples in the docs:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5)
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3)
[0, 3, 6, 9]
>>> range(0, -10, -1)
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]

Upvotes: 17

Related Questions