Reputation: 157
I came across a piece of code today that prompted me to write this little function:
def strangeloop(n):
for n in range(1, n):
print n
strangeloop(10) ended up printing numbers from 1 to 9. My question is, Why doesn't the loop variable conflict with the argument?
Upvotes: 0
Views: 357
Reputation: 15017
Pythons for
loops work different from c for
loops.
range
does not compare the running variable to its arguments.
It returns either a list of numbers (python2) or a generator that yield
s those numbers.
The for
loop then assigns one element after another to the running variable.
python2:
>>> l = range(5)
>>> l
[0, 1, 2, 3, 4]
python3:
>>> g = range(5)
>>> g
range(0, 5)
>>> list(g)
[0, 1, 2, 3, 4]
Upvotes: 1
Reputation: 251568
A for
loop assigns values to its loop variable(s) just like any other assignment. You can do your code for the same reason you can do this:
x = 2
x = 3
The later assignment just overwrites the earlier one. In your case, the loop variable overwrites the function argument.
Note that range(1, n)
is evaluated once, before the loop begins. So at that time it is referring to the function argument. Once that happens, the first loop value is assigned to n
, and then the function argument is overwritten and no longer accessible. The loop does not "need" the function argument once it is looping.
Upvotes: 3
Reputation: 1431
The answer is that range(1, n)
creates a range object, and when the for loop sets n
to the values in the range, it doesn't matter that the function parameter n
is being overwritten.
It might be less surprising that this code works fine, and it works for the same reason:
def strangeloop(n):
r = range(1, n):
for n in r:
print n
The value of n
is what is passed into the range, not the variable itself, so the range object cannot see that the variable n
has been changed.
Upvotes: 2