2016-12-02 256 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());