2017-09-27 6 views
0

このコードは、マージと分割のセクションでpymotw.comから出ます。Pythonで2つの連続したyield文がどのように機能しますか?

from itertools import * 


def make_iterables_to_chain(): 
    yield [1, 2, 3] 
    yield ['a', 'b', 'c'] 


for i in chain.from_iterable(make_iterables_to_chain()): 
    print(i, end=' ') 
print() 

make_iterables_to_chain()がどのように動作しているのか理解できません。これには2つの歩留り声明が含まれています 私は発電機の動作を知っていますが、そこにはという単収がありました。という声明がありました。

助けてください!

+0

は、おそらく唯一のyield文をありましたが、それはループではありませんでした。ここで

は、それが実現可能な方法ですか? –

+0

には2つあります。私は2つの利回りの基本を理解していませんでした。私は一度歩留まりに遭遇したら、それは他の歩留まりには向かないと思ったが、そうではない。 – ispeedster

答えて

0

yieldと同じ方法です。

__next__が呼び出されたときに、yieldを好きな数だけ持つことができます。__next__が呼び出されると、次の結果になるまで実行されます。次に、返された式を取得して、__next__メソッドが再び呼び出されるまで、ジェネレータは一時停止します。

を実行し、この参照するには発電機のnext通話のカップル:

>>> g = make_iterables_to_chain() # get generator 
>>> next(g) # start generator, go to first yield, get result 
[1, 2, 3] 
>>> next(g) # resume generator, go to second yield, get result 
['a', 'b', 'c'] 
>>> # next(g) raises Exception since no more yields are found 
0

発電機が効果的に機能が複数回を返すことができますが。 yieldステートメントが実行されるたびに、値が呼び出し元に返され、呼び出し元は関数の実行を続行できます。

通常、ループとしてforループの繰り返しとして使用されます。

次関数量だけ反復可能ですべての要素をインクリメント:ここ

def inc_each(nums, inc): 
    for i in nums: 
     yield i + inc 

は、使用の例である:

gen = inc_each([1, 2, 3, 4], 100) 
print(list(gen)) # [101, 102, 103, 104] 

listは、任意の反復可能に変換するためにここで使用されます(この場合はジェネレータ)をリストに追加します。

あなたが記述関数は二つの歩留まり文を実行します。

def make_iterables_to_chain(): 
    yield [1, 2, 3] 
    yield ['a', 'b', 'c'] 

あなたはそれを呼び出すと、それが通じ繰り返した場合、ジェネレーターを返し、リスト[1, 2, 3]['a', 'b', 'c']が得られます。

gen = make_iterables_to_chain() 
print(list(gen)) # [[1, 2, 3], ['a', 'b', 'c']] 

itertools.chain.from_iterableイテレート可能オブジェクトの(おそらく無限の)反復可能を取り、結果として反復可能(無限の可能)を返す、それを「平坦化」します。

def from_iterable(iterables): 
    for iterable in iterables: 
     for i in iterable: 
      yield i 
+0

最初にmake_iterables_to_chain()が呼び出されると、最初のyield文、すなわち[1,2,3]が与えられ、2回目に呼び出されると2番目のyield文が呼び出されることを意味しますか?['a'、 'b'、 'c'] – ispeedster

+0

@ispeedsterジェネレータの式には実際に間接的な層が追加されています。 'make_iterables_to_chain'を呼び出すと、' iter() 'と' next() 'を使って反復可能なジェネレータオブジェクト*を返します(通常は' for'ループによって自動的に処理されます)。そのため、関数自体は一度しか呼び出されませんが、結果オブジェクトは繰り返し処理され、複数の値を返すことができます。 – Challenger5

+0

ありがとう、私はそれがどのように働いているのか知っています。 – ispeedster

関連する問題