2016-12-02 9 views
3

編集:イテレータのリセットを扱うsimilar question hereがあります。以下の回答は、ネストされたイテレーターの実際の問題に対処しています。ネストされたイテレーターはリセットされないため、見逃しやすい問題を処理します。Python - イテレータを2回繰り返します。

イテレータをPythonで2回反復する方法はありますか?

次のコード例では、2番目の反復が最初のものと同じオブジェクトで動作していることが分かり、結果が変わっています。これを下のC#と比較すると、後の結果が得られます。

私がしたいことをする方法はありますか?私は、イテレータのコピーを作成するか、それが元の関数を "取得"できるかどうか疑問に思っていましたが、もっと簡単な方法があります。 (私はちょうどMyIter()を下記のおもちゃの例で2回呼び出すことができると知っていますが、イテレータがどこから来たのかわからないと役に立たなくなります。

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

与える:

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 

コントラストを与える

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が単一のiterableから独立イテレータを作成します。ただし、新しいiterableが作成されると、元のiterableはもう使用されません。

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()); 
関連する問題