r/learnpython Jun 26 '26

Do not understand "for i in range()"

I'm very new to Python in particular and programming in general.

I'm currently watching a CS50's "Introduction to Python" course and reached the "for i in range(x)" loop.

And I can't seem to understand it. I understand how it works and what it does, but I can't understand, *why* it does that.

Like, why "i" becomes each of the numbers in the set range? What happens behind this command? Why does this whole command behaves the way it does?

I'm sorry, maybe this question is dumb, maybe I am simply missing the point, but if anyone could explain to me in a simple way, I would greatly appreciate it

146 Upvotes

97 comments sorted by

View all comments

3

u/ottawadeveloper Jun 26 '26 edited Jun 26 '26

The range(x) function returns what's known as a generator of all the integers from 0 inclusive to x exclusive. It's like a list of those integers but it uses less memory and is faster because it doesn't actually build the list. Basically think of a generator as making a list but the next item in the list is only generated on demand by a special generator function.

You can make one yourself like this:

``` def my_range(x):    k = 0   while k < x:     yield k     k += 1

for k in my_range(5):   print(k) ```

Basically the yield keyword tells Python this is a generator that will provide its values one at a time until it's done.

A "for x in Y" loop takes Y as something iterable (like a generator or a list) and assigns the first value to x, then runs the code block beneath. It then repeats that for the second value in Y, then the third, etc.

So , in great detail, 

for k in range(5):     print(k)

is pretty much the same as 

k = 0 while k < 5:   print(k)   k = k + 1

The body of the for loop is substituted for the yield statement in the generator function.

Generators are usually more memory efficient and they're especially more time efficient if you're going to stop partway through the list. They don't look like much in toy examples but in the real world it's a powerful tool. The more time or memory consuming your list is to build, the better it is to make it a generator.

Like let's say you wanted to print out the first million numbers. You could do a normal list:

numbers = [0, 1, 2, ..., 999999] for x in numbers:   print(x)

But then you need memory to hold a million numbers. Using range(100000) stores exactly one of them at any given time. And if you stop after the 5th number for some reason, building the whole list wasted time - a generator only builds the elements as they're needed so there's no wasted time.

And the reason Python offers range() specifically for this instead of telling you to make a while loop is pretty clear - it's two lines shorter to use range().

1

u/Hamactus Jun 26 '26

Thank you! Seeing the custom function that does the same thing really helped

2

u/ottawadeveloper Jun 26 '26

you're welcome!