2012-07-16 5 views
8

ジェネレータを平滑化して別のジェネレータまたはiteables(別のジェネレータ/ iterablesを生成する可能性があります...無限大になる可能性があります)を生成するPython関数を記述する方法を知りたいと思います。ここPython:別のジェネレータを含むジェネレータをフラット化する機能

は一例であり:

gen(gen(1,2,3), gen(4,5,6), [7,8,9], [gen(10,11,12), gen(13,14,15)])

注:genからgen後の括弧の間にコンテンツがgen収率ジェネレータれるデータであり、ジェネレータオブジェクトを意味します。

「フラット化」の後に予想される結果: gen(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)

フラット化機能があまりにもジェネレータを返すことが必要です! (そうでなければ、先行する発電機の使用は無意味であろうから)。

ただ、注意すべき、私のpython 3.

感謝を使用しています!

答えて

12

最も簡単な方法は、再帰的平坦化機能です。あなたは、文字列を除くすべての反復可能に降りたいと仮定すると、あなたはこれを行うことができます:Pythonの3.3から始まっ

def flatten(it): 
    for x in it: 
     if (isinstance(x, collections.Iterable) and 
      not isinstance(x, str)): 
      for y in flatten(x): 
       yield y 
     else: 
      yield x 

、あなたはまた、非再帰的な方法は、本質的に展開され

def flatten(it): 
    for x in it: 
     if (isinstance(x, collections.Iterable) and 
      not isinstance(x, str)): 
      yield from flatten(x) 
     else: 
      yield x 
+0

ありがとうございました!私の試みで、私はあなたの近くにいました:-)よろしく! – JoshuaBoshi

+0

+1 - 私は 'yield from'を忘れています。これは素晴らしい思い出です。 –

+2

@JonClements:まだリリースされていないPythonバージョンの機能を "忘れてしまいますか?"私は驚いている。 :) –

0

書くことができます再帰的メソッド、スタックを使用して:

def flatten(it): 
    stack = [] 
    it = iter(it) 
    while True: 
     try: 
      x = next(it) 
     except StopIteration: 
      if stack: 
       it = stack.pop() 
       continue 
      else: 
       return 
     if isinstance(x, collections.Iterable) and not isinstance(x, str): 
      stack.append(it) 
      it = iter(x) 
     else: 
      yield x 
関連する問題