Python nested for loop behaviour
for-loop, nested-loops, python
Solution
The `for` loop assigns a new value to `i` every loop iteration, namely the next value taken from the loop iterable (in this case `range(16)`.
You can modify `i` in the loop itself, but that doesn't alter the iterable `for` is working with.
If you wanted to change the loop iterable, then you'd have to do so directly on the iterable:
loop_iterable = iter(range(16))
for i in loop_iterable:
if i == 0:
for j in range(8):
print 'i is (if) ' + str(i)
i = next(loop_iterable)
else:
print 'i is (else)' + str(i)
Here, we create a iterator object from the `range(10)` sequence by using the `iter()` function; the `for` statement does the exact same thing under the hood, but now we can address the iterator directly. The `next()` function advances the iterator to the next value, just like the `for` loop would do.
However, it may be easier to just use a `while` loop instead:
i = 0
while i < 16:
if i == 0:
for j in range(8):
print 'i is (if) ' + str(i)
i = next(loop_iterable)
else:
print 'i is (else)' + str(i)
i += 1
The thing to remember is that the Python `for` loop statement is nothing like a C or Java or JavaScript `for` loop. It is a Foreach loop instead. `range()` simply generates a sequence of numbers to loop over, as opposed to a C-style `for` loop, which combines the initial assignment (`i = 0`), test (`i < 16)`) and loop incrementer (`i += 1`) into one statement.
Problem
I came across this weird behaviour with nested for loops and I can't for the light of me explain this. Is this a python-specific thing or am I just overseeing something? This is the code I'm running: ``` for i in range(16): if i == 0: for j in range(8): print 'i is (if) ' + str(i) i = i + 1 else: print 'i is (else)' + str(i) ``` This is the output I'm getting: ``` i is (if) 0 i is (if) 1 i is (if) 2 i is (if) 3 i is (if) 4 i is (if) 5 i is (if) 6 i is (if) 7 i is (else)1 i is (else)2 i is (else)3 i is (else)4 i is (else)5 i is (else)6 i is (else)7 i is (else)8 i is (else)9 i is (else)10 i is (else)11 i is (else)12 i is (else)13 i is (else)14 i is (else)15 ``` This is the output I'm expecting: ``` i is (if) 0 i is (if) 1 i is (if) 2 i is (if) 3 i is (if) 4 i is (if) 5 i is (if) 6 i is (if) 7 i is (else)8 i is (else)9 i is (else)10 i is (else)11 i is (else)12 i is (else)13 i is (else)14 i is (else)15 ``` It seems like the i in the outer for loop and the i in the inner for loop are different variables, although that seems completely counterintuitive to me. Any input (I'm fairly new to python but couldn't find documentation on this)