2016-12-02 255 views
3

编辑:有一个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 
. . . 
+2

你可以在python中无限次迭代迭代器。但是,如果你引用生成器(你给出了代码的外观),那么发生器本身就无法多次这样做。但是,您可以将生成器结果保存在内存中并对其进行迭代。在你给出的例子中,你可以通过调用PrintCombos(list(MyIter()))' –

+0

['itertools.tee'](https://docs.python.org/3/library/itertools.html #itertools.tee)可能是你正在寻找的。 – Matthias

+0

[可以在Python中重置迭代器吗?]可能重复(http://stackoverflow.com/questions/3266180/can-iterators-be-reset-in-python) –

回答

1

你可以使用itertools.tee创建发电机

的多个副本
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()) 
-1

我发现使用列表理解这种类型的问题是最有效地得到您想要的结果。

x = [1,2,3,4] 
y = [1,2,3,4] 

spam = [[s,t] for s in x for t in y] 

for x in spam: 
    print('%s - %s' %(x[0], x[1])) 

输出:

1 - 1 
1 - 2 
1 - 3 
1 - 4 
2 - 1 
2 - 2 
2 - 3 
2 - 4 
3 - 1 
3 - 2 
3 - 3 
3 - 4 
4 - 1 
4 - 2 
4 - 3 
4 - 4 
1

itertools.tee创建从一个单一的可迭代独立迭代器。但是,一旦创建了新的迭代器,就不应该再使用原来的迭代器了。

import itertools 
def MyIter(): 
    yield 1; 
    yield 2; 
    yield 3; 
    yield 4; 

def PrintCombos(x): 
    xx = [] 
    xx.append(itertools.tee(x)) 
    n = 0 
    for a in xx[0][0]: 
     xx.append(itertools.tee(xx[n][1])) 
     for b in xx[n+1][0]: 
      print('%s - %s' % (a,b)); 
     n += 1 

PrintCombos(MyIter());