Why doesn't modifying the iteration variable affect subsequent iterations?
Почему изменение переменной iteration не влияет на последующие итерации?
Вот код Python, с которым у меня проблемы:
for i inrange (0,10): if i==5: i+=3 print i
Я ожидал, что результат будет:
0 1 2 3 4 8 9
Однако интерпретатор выдает:
0 1 2 3 4 8 6 7 8 9
Я знаю, что for цикл создает новую область видимости для переменной в C, но понятия не имею о Python. Почему значение i не изменяется в for цикле в Python и как можно исправить это, чтобы получить ожидаемый результат?
Смотрите Как изменять записи списка во время цикла for? о том, как изменить исходную последовательность. В 3.x, конечно, range создает неизменяемый объект, поэтому он все равно не будет работать.
Переведено автоматически
Ответ 1
Цикл for выполняет итерацию по всем числам в range(10), то есть [0,1,2,3,4,5,6,7,8,9]. То, что вы изменяете текущее значение i, не влияет на следующее значение в диапазоне.
Вы можете добиться желаемого поведения с помощью цикла while.
i = 0 while i < 10: # do stuff and manipulate `i` as much as you like if i==5: i+=3
print i
# don't forget to increment `i` manually i += 1
Ответ 2
Аналогия с кодом на C
Вы воображаете, что ваш for-loop в python похож на этот код на C:
for (int i = 0; i < 10; i++) if (i == 5) i += 3;
Это больше похоже на этот код на C:
int r[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (int j = 0; j < sizeof(r)/sizeof(r[0]); j++) { int i = r[j]; if (i == 5) i += 3; }
Таким образом, изменение i в цикле не дает ожидаемого эффекта.
A for loop in Python is actually a for-each loop. At the start of each loop, i is set to the next element in the iterator (range(0, 10) in your case). The value of i gets re-set at the beginning of each loop, so changing it in the loop body does not change its value for the next iteration.
That is, the for loop you wrote is equivalent to the following while loop:
If for some reason you did really want to change add 3 to i when it's equal to 5, and skip the next elements (this is kind of advancing the pointer in C 3 elements), then you can use an iterator and consume a few bits from that:
from collections import deque from itertools import islice
x = iter(range(10)) # create iterator over list, so we can skip unnecessary bits for i in x: if i == 5: deque(islice(x, 3), 0) # "swallow up" next 3 items i += 3# modify current i to be 8 print i