Редактировать: Существует similar question here, который имеет дело с сбросом итератора. В принятом ниже ответе решается актуальная проблема вложенных итераторов и обрабатывается легко пропустить проблему, при которой вложенный итератор не сбрасывается.Python - Итерация итератора дважды
Есть ли способ перебрать итератор дважды в python?
В приведенном ниже примере кода я вижу, что вторая итерация работает на том же объекте, что и первая, и, таким образом, дает странный результат. Сравните это с C# ниже, что дает результат, который я получил после.
Есть ли способ делать то, что я хочу. Мне было интересно, могу ли я сделать копию итератора или «восстановить» функцию, из которой он пришел, но, возможно, есть более простой способ. (Я знаю, что я мог бы просто позвонить MyIter()
дважды в примере с игрушкой ниже, но это бесполезно, если я не знаю, откуда итератор пришел, и не то, что мне нужно!).
def MyIter():
yield 1;
yield 2;
yield 3;
yield 4;
def PrintCombos(x):
for a in x:
for b in x:
print(a,"-",b);
PrintCombos(MyIter());
дает
1 - 2
1 - 3
1 - 4
Контраст с:
static IEnumerable MyIter()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
}
static void PrintCombos(IEnumerable x)
{
foreach (var a in x)
foreach (var b in x)
Console.WriteLine(a + "-" + b);
}
public static void Main(String[] args)
{
PrintCombos(MyIter());
}
Что дает:
1-1
1-2
1-3
1-4
2-1
2-2
. . .
Вы можете перебирать итераторы неограниченное количество раз в python. Однако, если вы ссылаетесь на генераторы (которые вы видите по внешнему виду кода), нет никакого способа сделать это несколько раз на самом генераторе. Однако вы можете сохранить результаты генератора в памяти и перебрать их. В приведенном вами примере вы сделаете это, вызвав 'PrintCombos (список (MyIter())) –
[' itertools.tee'] (https://docs.python.org/3/library/itertools.html # itertools.tee) может быть то, что вы ищете. – Matthias
Возможный дубликат [Итераторы могут быть сброшены в Python?] (Http://stackoverflow.com/questions/3266180/can-iterators-be-reset-in-python) –