Объяснение новой концепции
Понятие итераторов было введено в Python версии 2.2. Хотя это не совсем верно; намеки на эту идею присутствовали уже в более ранней функции xrange() и в файловом методе .xreadlines(). Python 2.2 обобщил это понятие в большей части своих внутренних реализаций и значительно упростил программирование итераторов, определенных пользователем, введя ключевое слово yield (присутствие yield превращает функцию в генератор, который в свою очередь возвращает итератор).
Привлекательность итераторов объясняется двумя причинами. Работа с данными как последовательностями - часто наиболее простой подход, а последовательность, обрабатываемая в линейном порядке, на самом деле зачастую не должна существовать вся сразу.
Предупреждения x*() предоставляют очевидные примеры этих принципов. Если вы хотите сделать что-нибудь миллиард раз, ваша программа, вероятно, будет исполняться какое время, однако, в общем не нужно требовать для нее много памяти. Подобным образом для многих типов файлов обработка может выполняться построчно, и нет необходимости хранить в памяти весь файл. Все виды других последовательностей также можно наилучшим образом подвергнуть отложенному вычислению; они могли бы полагаться на данные, поступающие в виде приращений по каналу, или на вычисления, выполняемые шаг за шагом.
Большую часть времени итератор используется в цикле for точно так же, как и истинная последовательность. Итераторы предоставляют метод .next(), который может быть явно запущен, но в 99% времени то, что вы увидите - это что-нибудь вроде:
for x in iterator: do_something_with(x)
Этот цикл завершается, когда закулисное обращение к iterator.next() возбуждает исключение StopIteration. Между прочим, истинная последовательность может быть превращена в итератор вызовом iter(seq) - это нисколько не сбережет память, но может быть полезно в функциях, обсуждаемых ниже.