Yield in Python チュートリアル:Generator &Yield vs Return の例
Python 収量とは
Python の yield キーワードは、唯一のリターンのように機能します
違いは、値を返す代わりに、ジェネレーター オブジェクトを呼び出し元に返すことです。
関数が呼び出され、実行スレッドが関数内に yield キーワードを見つけると、関数の実行はその行自体で停止し、ジェネレーター オブジェクトを呼び出し元に返します。
この Python チュートリアルでは、次のことを学びます:
- Python の利回りとは?
- 構文
- Python のジェネレーターとは?
- ノーマル関数とジェネレータ関数の違い。
- ジェネレータから値を読み取る方法は?
- ジェネレーターは 1 回限りの使用
- 例:フィボナッチ数列のジェネレーターと利回り
- 例:Yield を指定して関数を呼び出す
- Python で Return の代わりに Yield を使用する場合
- 利回りとリターン
構文
yield expression
説明
Python yield はジェネレータ オブジェクトを返します。ジェネレーターは、値を取得するために反復する必要がある特別な関数です。
yield キーワードは、指定された式をジェネレーター オブジェクトを返すジェネレーター関数に変換します。オブジェクトの値を取得するには、yield に指定された値を読み取るために反復する必要があります。
例:イールド法
これは利回りの簡単な例です。関数 testyield() には、文字列「Welcome to Guru99 Python Tutorials」を含む yield キーワードがあります。関数が呼び出されると、出力が出力され、実際の値の代わりにジェネレーター オブジェクトが提供されます。
def testyield(): yield "Welcome to Guru99 Python Tutorials" output = testyield() print(output)
出力:
<generator object testyield at 0x00000028265EB9A8>
与えられた出力は生成器オブジェクトであり、yield に与えた値を持っています。
しかし、出力でyieldするために与えなければならないメッセージを受け取っていません!
yield に与えられたメッセージを出力するには、以下の例に示すようにジェネレーター オブジェクトを反復する必要があります:
def testyield(): yield "Welcome to Guru99 Python Tutorials" output = testyield() for i in output: print(i)
出力
Welcome to Guru99 Python Tutorials
Python のジェネレーターとは?
ジェネレーターは、反復可能なジェネレーター オブジェクトを返す関数です。ジェネレーター オブジェクトからの値は、完全なリストをまとめて取得するのではなく、一度に 1 つずつ取得されるため、実際の値を取得するには、next() または list() メソッドを使用して for ループを使用できます。
ジェネレーター機能の使用
ジェネレーター関数とジェネレーター式を使用してジェネレーターを作成できます。
ジェネレーター関数は、通常の関数と同様に、戻り値を持つ代わりに、yield キーワードを持ちます。
ジェネレーター関数を作成するには、yield キーワードを追加する必要があります。次の例は、ジェネレーター関数を作成する方法を示しています。
def generator(): yield "H" yield "E" yield "L" yield "L" yield "O" test = generator() for i in test: print(i)
出力:
H E L L O
ノーマル関数とジェネレータ関数の違い
ジェネレーター関数が通常の関数とどのように異なるかを理解しましょう。
normal_test() と generator_test() の 2 つの関数があります。
どちらの関数も、文字列「Hello World」を返すと想定されています。 normal_test() は return を使用し、generator_test() は yield を使用しています。
# Normal function def normal_test(): return "Hello World" #Generator function def generator_test(): yield "Hello World" print(normal_test()) #call to normal function print(generator_test()) # call to generator function
出力:
Hello World <generator object generator_test at 0x00000012F2F5BA20>
出力は、通常の関数 normal_test() を呼び出すと、Hello World 文字列が返されることを示しています。 yield キーワードを持つジェネレーター関数の場合、文字列ではなく
これが、ジェネレーター関数と通常の関数の主な違いです。ジェネレーター オブジェクトから値を取得するには、for ループ内でオブジェクトを使用するか、next() メソッドを使用するか、list() を使用する必要があります。
print(next(generator_test())) # will output Hello World
通常の関数とジェネレーター関数に追加するもう 1 つの違いは、通常の関数を呼び出すと、実行が開始され、return に到達すると停止することです。 値が呼び出し元に返されます。したがって、実行が開始されると、通常の関数を途中で停止することはできず、 return キーワードに遭遇したときにのみ停止します。
ただし、ジェネレーター関数の場合、最初のyieldを取得したときに実行が開始されると、実行が停止し、ジェネレーターオブジェクトが返されます。ジェネレーター オブジェクトを使用して値を取得したり、必要に応じて一時停止したり再開したりできます。
ジェネレーターから値を読み取る方法
list()、for-loop、および next() メソッドを使用して、ジェネレータ オブジェクトから値を読み取ることができます。
使用:list()
リストは、括弧内に要素を持つ反復可能なオブジェクトです。ジェネレーター オブジェクトで list() を使用すると、ジェネレーターが保持するすべての値が得られます。
def even_numbers(n): for x in range(n): if (x%2==0): yield x num = even_numbers(10) print(list(num))
出力:
[0, 2, 4, 6, 8]
使用:for-in
この例では、定義された n に対してすべての偶数を与える関数定義 even_numbers() があります。関数 even_numbers() を呼び出すと、for ループ内で使用されるジェネレーター オブジェクトが返されます。
例:
def even_numbers(n): for x in range(n): if (x%2==0): yield x num = even_numbers(10) for i in num: print(i)
出力:
0 2 4 6 8
next() の使用
next() メソッドは、リスト、配列、またはオブジェクトの次の項目を提供します。リストが空になり、next() が呼び出されると、stopIteration シグナルでエラーが返されます。 next() からのこのエラーは、リストに項目がないことを示しています。
def even_numbers(n): for x in range(n): if (x%2==0): yield x num = even_numbers(10) print(next(num)) print(next(num)) print(next(num)) print(next(num)) print(next(num)) print(next(num))
出力:
0 2 4 6 8 Traceback (most recent call last): File "main.py", line 11, in <module> print(next(num)) StopIteration
ジェネレーターは 1 回限りの使用です
ジェネレーターの場合、一度しか使用できません。もう一度使用しようとすると、空になります。
例:
def even_numbers(n): for x in range(n): if (x%2==0): yield x num = even_numbers(10) for i in num: print(i) print("\n") print("Calling the generator again: ", list(num))
出力:
0 2 4 6 8 Calling the generator again: []
出力を再度使用する場合は、関数を再度呼び出す必要があります。
例:フィボナッチ数列のジェネレーターと利回り
次の例は、Python でジェネレーターと yield を使用する方法を示しています。この例は、フィボナッチ数列を生成します。
def getFibonnaciSeries(num): c1, c2 = 0, 1 count = 0 while count < num: yield c1 c3 = c1 + c2 c1 = c2 c2 = c3 count += 1 fin = getFibonnaciSeries(7) print(fin) for i in fin: print(i)
出力:
<generator object getFibonnaciSeries at 0x0000007F39C8BA20> 0 1 1 2 3 5 8
例:Yield を指定して関数を呼び出す
この例では、yield を使用して関数を呼び出す方法を示します。
以下の例には、指定された数値の 2 乗を返す test() という関数があります。テスト()をyieldキーワードで使用するgetSquare()と呼ばれる別の関数があります。出力は、指定された数値範囲の二乗値を示します。
def test(n): return n*n def getSquare(n): for i in range(n): yield test(i) sq = getSquare(10) for i in sq: print(i)
出力:
0 1 4 9 16 25 36 49 64 81
Python で Return の代わりに Yield を使用する場合
Python3 収量 キーワードはジェネレーターを呼び出し元に返し、コードの実行はジェネレーターが反復されたときにのみ開始されます。
返品 関数内の は関数実行の終了であり、単一の値が呼び出し元に返されます。
Return の代わりに Yield を使用する必要がある状況は次のとおりです
- データ サイズが大きい場合は、return の代わりに yield を使用します
- 大規模なデータセットで実行を高速化する必要がある場合は、Yield が最適です
- 大きな値のセットを呼び出し元の関数に返したい場合はyieldを使用してください
- 収量は、大量または無限のデータを生成する効率的な方法です。
利回りとリターン
ここに、イールドとリターンの違いがあります
利回り | 戻る |
---|---|
Yield はジェネレーター オブジェクトを呼び出し元に返し、コードの実行はジェネレーターが反復されたときにのみ開始されます。 | 関数のリターンは関数の実行の終了であり、単一の値が呼び出し元に返されます。 |
関数が呼び出され、yield キーワードに遭遇すると、関数の実行が停止します。ジェネレーター オブジェクトを呼び出し元に返します。関数の実行は、ジェネレータ オブジェクトが実行されたときにのみ開始されます。 | 関数が呼び出されると実行が開始され、return キーワードがあれば呼び出し元に値が返されます。関数内の return は、関数の実行の終了を示します。 |
利回り式 | リターン式 |
yield キーワードが使用されている場合、メモリは使用されません。 | 返された値にメモリが割り当てられます。 |
メモリを使用しないため、巨大なデータ サイズを処理する必要がある場合に非常に便利です。 | データ サイズが非常に小さい場合に便利です。 |
yield キーワードを大きなデータ サイズに使用すると、パフォーマンスが向上します。 | データ サイズが大きい場合、大量のメモリが使用され、パフォーマンスが低下します。 |
データ サイズが大きい場合、実行時間が短縮されます。 | データ サイズが大きい場合に余分な処理が行われるため、使用される実行時間は長くなりますが、データ サイズが小さい場合は問題なく動作します。 |
まとめ:
- Python の yield キーワードは return のように機能しますが、唯一の違いは、値を返す代わりに、呼び出し元にジェネレーター関数を返すことです。
- ジェネレーターは、一度使用すると二度と使用できない特別なタイプのイテレーターです。値はメモリに保存されず、呼び出されたときにのみ使用できます。
- ジェネレーターからの値は、for-in、list()、および next() メソッドを使用して読み取ることができます。
- yield と return の主な違いは、yield はジェネレータ関数を呼び出し元に返し、return は単一の値を呼び出し元に返すことです。
- Yield は値をメモリに格納しません。値がメモリに格納されないため、データ サイズが大きい場合に便利です。
- yield キーワードを使用すると、大きなデータ サイズを返すよりもパフォーマンスが向上します。
Python