Я думаю, вы неправильно поняли, что такое «объект итератора». Цикл for
не является объектом итератора. Для всех целей и целей такой цикл цикла:
myList = [0, 1, 2, 3, 4]
for x in myList:
print x
делает это (но более эффективно и менее подробно):
i = 0
while i < len(myList)
x = myList[i]
print x
i += 1
Итак, вы видите, что любые изменения сделаны на x
теряются, как только начинается следующий цикл, потому что значение x
перезаписывается значением следующего элемента в списке.
Как и другие наблюдатели, можно изменить значение списка при его итерации по нему. (Но не изменяйте его длину! Вот где вы попадаете в неприятности.) Один из элегантных способов сделать это выглядит следующим образом:
for i, x in enumerate(myList):
myList[i] = some_func(x)
Обновление: также важно понимать, что нет копирования продолжается в цикле for. В приведенном выше примере i
и x
- как и все переменные в Python - больше похожи на указатели в C / C ++. По мере продвижения цикла for obj
указывает на myList[0]
, myList[1]
и т. Д., В свою очередь. И как указатель C / C ++, свойства объекта, на который указывает, не изменяются при изменении указателя. Но также как и указатель C, вы можете напрямую изменить указав на вещь, потому что это не копия. В C это выполняется с помощью разыменования указателя; в Python это делается с помощью изменяемого объекта. Вот почему работает ответ NPE . Если i
и x
были даже неглубокими копиями, было бы невозможно делать то, что он делает.
Причина, по которой вы не можете напрямую изменить int
так, как вы можете изменить list
s (как в ответе NPE), заключается в том, что int
s не изменяются. Когда объект 5
создается, ничто не может изменить его значение. Вот почему прохождение вокруг указателя 5
безопасно в Python - никаких побочных эффектов не может быть, потому что указанная вещь неизменна.