Reputation: 2159
CODE 1:
>>> data = ['A', 'B', 'C', 'D']
>>> for i, x in enumerate(data, 1):
print(i, x)
CODE 2:
>>> data = ['A', 'B', 'C', 'D']
>>> for i, x in enumerate(data, 1):
print(i, x)
i += 1
RESULT (for both):
1 A
2 B
3 C
4 D
Why does incrementing in the second code have no effect on the result?
Upvotes: 1
Views: 115
Reputation: 14474
Some insight can be found by taking a look at the byte code that CPython produces in your second example:
>>> from dis import dis
>>> def with_increment():
for i, x in enumerate(data, 1):
print(i, x)
i += 1
>>> dis(with_increment)
2 0 SETUP_LOOP 40 (to 42)
2 LOAD_GLOBAL 0 (enumerate)
4 LOAD_GLOBAL 1 (data)
6 LOAD_CONST 1 (1)
8 CALL_FUNCTION 2
10 GET_ITER
>> 12 FOR_ITER 26 (to 40)
14 UNPACK_SEQUENCE 2
16 STORE_FAST 0 (i)
18 STORE_FAST 1 (x)
3 20 LOAD_GLOBAL 2 (print)
22 LOAD_FAST 0 (i)
24 LOAD_FAST 1 (x)
26 CALL_FUNCTION 2
28 POP_TOP
4 30 LOAD_FAST 0 (i)
32 LOAD_CONST 1 (1)
34 INPLACE_ADD
36 STORE_FAST 0 (i)
38 JUMP_ABSOLUTE 12
>> 40 POP_BLOCK
>> 42 LOAD_CONST 0 (None)
44 RETURN_VALUE
The part we're interested in is bytes 12-38, which correspond to the body of the loop. Each iteration starts by performing the following actions in sequence:
UNPACK_SEQUENCE 2
- The components of the tuple produced by enumerate
are pushed onto the stack.
STORE_FAST 0
- The value on the top of the stack is stored in the first local variable (i
).
STORE_FAST 1
- The value on the top of the stack is stored in the second local variable (x
).
The key thing to note here is that we never look at the current value of i
---each iteration blindly overwrites it with whatever was produced by the iterator. Whatever object used to be in i
during the previous iteration is completely forgotten.
Upvotes: 1
Reputation: 71542
The i
value you get from the iteration is the output of the enumerate
function, not an input to it.
Modifying it does not affect the course of the enumeration, and the for...in
loop will continually overwrite the variable with whatever enumerate
produces, regardless of what you set it to within the loop body.
Unlike Java and C, loops in python iterate over iterables. They don't depend on counters.
Upvotes: 3