2

Sorry for the noob question, but someone pls explain me the inner workings of this nested for loop.

v,w = 2,4
for v in range(v):
   for w in range(w):
        print('v=',v,'w=',w)

If I run it like this, the output will be as follows:

v= 0 w= 0
v= 0 w= 1
v= 0 w= 2
v= 0 w= 3
v= 1 w= 0
v= 1 w= 1
v= 1 w= 2

I figured it stops 'prematurely' (the last output v= 1 w= 3 is missing) cause the last value assigned to the 'w' variable was 3 before the last loop ran.

If I run it like this, it works, but doesn't look Pythonic to say the least.

v,w = 2,4
for v in range(v):
    for w in range(w):
        print('v=',v,'w=',w)
    w = 4

Could some please explain how this problem is best addressed?

3
  • 1
    Variables leak from loops. Your w ends at 3 after first iteration of outer loop. Commented Feb 12, 2018 at 17:06
  • 1
    What is the problem ? Commented Feb 12, 2018 at 17:06
  • 1
    You need to use different temporarily variable during the iteration. For example for v_ in range(v): for w_ in range(w) Commented Feb 12, 2018 at 17:06

4 Answers 4

6

I figured it stops 'prematurely' (the last output v= 1 w= 3 is missing) cause the last value assigned to the 'w' variable was 3 before the last loop ran

Correct.

Could some please explain how this problem is best addressed?

Don't re-use the same local variable name for two different meanings:

n_v, n_w = 2, 4
for v in range(n_v):
   for w in range(n_w):
        print('v=', v, 'w=', w)
Sign up to request clarification or add additional context in comments.

2 Comments

Was writing this. In addition, I'd point the OP to pythontutor.com
Although extremely confusing and ugly, if the loops are not nested, re-using the same variable is not an issue. In my opinion this has to be noted.
1

This behavior is known as variable leaking in for loops and is due to the fact that Python does not create a new variable in for loops.

At the end of for w in range(w):, w has value 3 so when you run the loop again it will run for range(3) and for range(4) with the original value of w as you might have expected.

To avoid this, use a different variable for in the for loop, as suggested in the other answers.

The only case when the for loop variable is not exposed to the surrounding function is in list comprehensions (and only in Python 3, see PEP- Generator Expressions), so for instance

>>> for v in range(v):
...    print([('v=',v,'w=',w) for w in range(w)])
...    print(w)
...
[('v=', 0, 'w=', 0), ('v=', 0, 'w=', 1), ('v=', 0, 'w=', 2), ('v=', 0, 'w=', 3)]
4
[('v=', 1, 'w=', 0), ('v=', 1, 'w=', 1), ('v=', 1, 'w=', 2), ('v=', 1, 'w=', 3)]
4

Comments

1

The most interesting thing to notice here in my opinion is that range(w) is not updated as long as you stay in the same for v in range(v) iteration. And that is why you get:

v = 0,  w = 0
v = 0,  w = 1
v = 0,  w = 2
v = 0,  w = 3

But, on the second iteration, when your v becomes 1, range(w) gets redefined using the new w value which is now 3. And that is why you then get:

v = 1,  w = 0
v = 1,  w = 1
v = 1,  w = 2

Addressing the problem as for example @wim says is simple; you just have to use different variables:

for i in range(v):
    for j in range(w):
        # do your thing

A side-effect of the above is that the following does execute 5 times even though it is a horrible thing to write:

v = 5
for v in range(v):
    # do your thing

Comments

0

Hi Peter see the answer from wim he is correct.

Rewrite the code like below:-

v,w = 2,4
  for v1 in range(v):
     for w1 in range(w):
         print('v=',v1,'w=',w1)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.