What happened when using the same variable in double layer loops in python?

I am testing the following code:

for i in range(3): for i in range(3,5): print "inner i: %d"%(i) print "outer i: %d"%(i) 

and output:

 inner i: 3 inner i: 4 outer i: 4 inner i: 3 inner i: 4 outer i: 4 inner i: 3 inner i: 4 outer i: 4 

I do not understand why in the outer loop i is 4, but the outer loop is still running 3 times. It seems that the variable i in the line print "outer i: %d"%(i) is i in the inner loop, but when it goes to for i in range(3) , it uses i in the outer loop.

Can anyone explain this? This is a bit confusing to me now.

+7
scope python
source share
6 answers

The same i , Python does not have a block area. At the beginning of each for-loop iteration, you assign the next value in the iterator to i . Python for-loops is not like C / Java for-loops, these are foreach loops. Continue until the iterator is exhausted (or you break somehow). A for-loop is equivalent to the following while-loop:

 iterator = iter(my_iterable) while True: try: x = next(iterator) except StopIteration: break do_stuff(x) 

So your nested loop is equivalent to this:

 it1 = iter(range(3)) while True: try: i = next(it1) except StopIteration: break it2 = iter(range(3, 5)) while True: try: i = next(it2) except StopIteration: break print "inner i: %d"%(i) print "outer i after: %d"%(i) 

Note: C / Java for-loop, for example:

 for (int i = 0; i < stop; i++){ do_stuff(i); } 

Will be in Python:

 i = 0 while i < stop: do_stuff(i) i += 1 

In other words, the classic for the loop depends on i , that is, the termination condition depends on the value of i . But in a for-each loop, the termination condition depends on the iterator. And no matter what you do with the variable inside the body, at the beginning of each iteration, it is assigned the next value of the iterator.

+13
source share

In the inner loop, you assign another variable i. Since this is the same variable, it always prints 4 (the last value I was assigned in the inner loop. However, when you go to the next iteration of the outer loop, it will be set to the next value (i.e. 2 for the second outer loop) You must print the outer loop before the inner loop to see the effect more clearly:

 for i in range(3): print "outer i before:%d"%(i) for i in range(3,5): print "inner i: %d"%(i) print "outer i after: %d"%(i) 
+6
source share

Note that the output is always

 inner i: 3 inner i: 4 outer i: 4 

for every outer loop.

In each iteration, the program takes the final value i .

that is, when the outer loop starts execution, i is either 0, 1 or 2, but the value of i changes in the inner loop that is being printed.

Update:

 for i in range(3): for i in range(3,5): print (id(i)) print (id(i)) 

Exit

 1372154016 1372154032 1372154032 1372154016 1372154032 1372154032 1372154016 1372154032 1372154032 
+3
source share

Only one i , not two. When the inner loop is entered, it changes i and continues to change it until the inner loop exits. The next iteration of the outer loop then sets i to the next value in its range, but you will never see it, because you immediately enter the inner loop again, changing i again.

This, of course, is a very bad practice. You should not change a variable in a for loop while this loop is active.

+2
source share

Its the same self used in both cycles. When the outer contours get the opportunity to print i, it will always have the last assigned value from the inner loop.

+2
source share

Check out @heltonbiker's answer:

 >>> for i in range(3): print "1-",locals() for i in range(3,5): print "2-",locals() 1- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 0, '__name__': '__main__', '__doc__': None} 2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 3, '__name__': '__main__', '__doc__': None} 2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 4, '__name__': '__main__', '__doc__': None} 1- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 1, '__name__': '__main__', '__doc__': None} 2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 3, '__name__': '__main__', '__doc__': None} 2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 4, '__name__': '__main__', '__doc__': None} 1- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 2, '__name__': '__main__', '__doc__': None} 2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 3, '__name__': '__main__', '__doc__': None} 2- {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'i': 4, '__name__': '__main__', '__doc__': None} >>> 

You are reading i data at the wrong time (place)!

If there is one BUS or Variable name , you should use the FIFO method.

FIFO <<Here is the information

+1
source share

All Articles