Из-за утиного ввода Python,
Любой объект повторяем, если он определяет next()
и __iter__()
метод возвращает себя.
Если сам объект не имеет next()
метод, __iter__()
может возвратить любой объект, который имеет a next()
метод
Вы могли отослать этот вопрос видеть Iterability в Python
import itertools
def process(iterable):
work_iter, backup_iter= itertools.tee(iterable)
for item in work_iter:
# bla bla
if need_to_startover():
for another_item in backup_iter:
Та проклятая машина времени, которую Raymond одолжил от Guido …
Однако существует важное семантическое различие между двумя...
Едва ли семантический или важный. Они оба повторяемы - они оба работа с для оператора.
Различие, например, важно, когда каждый хочет циклично выполниться многократно.
Когда это когда-либо подходит? Необходимо будет быть более конкретными. В редких случаях, когда необходимо сделать два, проходит через повторяемый набор, часто существуют лучшие алгоритмы.
Например, скажем, Вы обрабатываете список. Можно выполнить итерации через список всего, что Вы хотите. Почему Вы попадали в историю с итератором вместо повторяемого? Хорошо это не работало.
Хорошо, вот тот. Вы читаете файл в двух передачах, и необходимо знать, как сбросить повторяемое. В этом случае это - файл, и seek
требуется; или завершение и вновь открывание. Это чувствует себя неприглядным. Вы можете readlines
получить список, который позволяет две передачи без сложности. Таким образом, это не необходимо.
Ожидайте, что, если у нас есть файл, настолько большой, мы не можем считать все это в память? И по неясным причинам мы не можем искать, также. Что затем?
Теперь, мы до основных элементов двух передач. На первичной обработке мы накопили что-то. Индекс или сводка или что-то. Индекс имеет данные всего файла. Сводка, часто, является реструктуризацией данных. С небольшим изменением из "сводки" для "реструктурирования" мы сохранили данные файла в новой структуре. В обоих случаях нам не нужен файл - мы можем использовать индекс или сводку.
Все алгоритмы "с двумя передачами" могут быть изменены на одну передачу исходного итератора или повторяемые и вторую передачу другой структуры данных.
Это ни один LYBL или EAFP. Это - дизайн алгоритма. Вы не должны сбрасывать итератор - YAGNI.
Править
Вот пример проблемы итератора / повторяемой проблемы. Это - просто плохо разработанный алгоритм.
it = iter(xrange(3))
for i in it: print i,; #prints 1,2,3
for i in it: print i,; #prints nothing
Это тривиально фиксируется.
it = range(3)
for i in it: print i
for i in it: print i
"Многократно параллельно" тривиально фиксируется. Запишите API, который требует повторяемого. И когда кто-то отказывается читать документацию API или отказывается следовать за нею считав ее, их повреждения материала. Как это должно.
"Хороший охранять против случая был пользователь, обеспечивает только итератор, когда несколько передач необходимы", оба примеры безумных людей написание кода, которое повреждает наш простой API.
Если кто-то достаточно безумен, чтобы считать большинство (но не весь документ API) и обеспечить итератор, когда повторяемое требовалось, необходимо найти этого человека и преподавать их (1) как прочитать всю документацию API и (2) следуете документации API.
Проблема "гарантии" не очень реалистична. Эти сумасшедшие программисты удивительно редки. И в нескольких случаях, когда это действительно возникает, Вы знаете, кто они и могут помочь им.
Редактирование 2
"Мы должны читать, та же структура многократно" алгоритмы являются фундаментальной проблемой.
Не делайте этого.
for element in someBigIterable:
function1( element )
for element in someBigIterable:
function2( element )
...
Сделайте это, вместо этого.
for element in someBigIterable:
function1( element )
function2( element )
...
Или, рассмотрите что-то вроде этого.
for element in someBigIterable:
for f in ( function1, function2, function3, ... ):
f( element )
В большинстве случаев этот вид "центра" Ваших алгоритмов приводит к программе, которую могло бы быть легче оптимизировать и могла бы быть сетевым улучшением производительности.