Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
718 views
in Technique[技术] by (71.8m points)

for loop - Python -- Iterate an iterator twice

Edit: There is a similar question here that deals with iterator resetting. The accepted answer below however addresses the actual issue of nested iterators, and handles an easy to miss issue, whereby the nested iterator doesn't reset.

Is there any way to iterate over an iterator twice in python?

In the example code below I can see that the second iteration is operating on the same object as the first, and thus yields a weird result. Contrast this with the C# below that yields the result I'm after.

Is there any way to do what I want. I was wondering if I could make a copy of the iterator or "retrieve" the function it came from, but maybe there's a simpler way. (I know I could just call MyIter() twice in the toy example below, but that's useless if I don't know where the iterator came from and isn't what I'm after!).

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());

gives

1 - 2
1 - 3
1 - 4

Contrast with:

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());
}

Which gives:

1-1
1-2
1-3
1-4
2-1
2-2
. . .
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could use itertools.tee to create multiple copies of the generator

from itertools import tee

def MyIter():
    yield 1
    yield 2
    yield 3
    yield 4

def PrintCombos(x):
    it1, it2 = tee(x, 2)
    for a in it1:
        it2, it3 = tee(it2, 2)
        for b in it3:
        print("{0}-{1}".format(a, b))

PrintCombos(MyIter())

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...