降伏 Python チュートリアル: Generator & 利回りと収益の例

何ですか Python 収率?

Python の yield キーワードは、唯一の return のように機能します。

違いは、値を返す代わりに、呼び出し元にジェネレータ オブジェクトを返すことです。

関数が呼び出され、実行スレッドが関数内で yield キーワードを見つけると、関数の実行はその行で停止し、ジェネレーター オブジェクトを呼び出し元に返します。

構文

yield expression

詳細説明

Python yield はジェネレーター オブジェクトを返します。 Generatorは、値を取得するために反復する必要がある特別な関数です。

yield キーワードは、指定された式をジェネレーター オブジェクトを返すジェネレーター関数に変換します。オブジェクトの値を取得するには、yield に指定された値を読み取るために反復処理を実行する必要があります。

例: 収量法

yield の簡単な例を以下に示します。関数 testyield() には、文字列「Welcome to Guru99 Python チュートリアル「関数が呼び出されると、出力が印刷され、実際の値の代わりにジェネレーター オブジェクトが提供されます。

def testyield():
  yield "Welcome to Guru99 Python Tutorials"
output = testyield()
print(output)

出力:

<generator object testyield at 0x00000028265EB9A8>

出力は、yield に指定した値を持つジェネレーター オブジェクトです。

しかし、出力に与えるために与えなければならないメッセージが得られません。

yield に与えられたメッセージを印刷するには、次の例に示すようにジェネレーター オブジェクトを反復処理する必要があります。

def testyield():
  yield "Welcome to Guru99 Python Tutorials"

output = testyield()
for i in output:
    print(i)

出力:

Welcome to Guru99 Python Tutorials

何ですか Generators内 Python?

Generatorは、反復可能なジェネレーター オブジェクトを返す関数です。ジェネレーター オブジェクトからの値は、完全なリストをまとめて取得するのではなく、一度に 1 つずつ取得されるため、実際の値を取得するには、next() または list() メソッドを使用して for ループを使用できます。

使い方 Generator function

ジェネレーター関数とジェネレーター式を使用してジェネレーターを作成できます。

ジェネレータ関数は通常の関数と似ていますが、戻り値の代わりに 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

通常の機能との違い Generator 機能。

ジェネレータ関数が通常の関数とどう違うのかを理解しましょう。

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 ループ、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

Generatorは XNUMX 回限りの使用です

ジェネレーターは一度しか使用できません。再度使用しようとすると空になります。

具体的な例を挙げますと、以下の通りです。

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:  []

出力を再度使用したい場合は、関数を再度呼び出す必要があります。

例: Generatorフィボナッチ数列の s と利回り

次の例は、ジェネレータとyieldの使い方を示しています。 Pythonこの例では、フィボナッチ数列を生成します。

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 を使用して関数を呼び出す方法を示します。

以下の例には、指定された数値の XNUMX 乗を返す test() という関数があります。 getSquare() と呼ばれる別の関数があります。これは、yield キーワードを指定して test() を使用します。 出力では、指定された数値範囲の二乗値が得られます。

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

Returnの代わりにYieldを使うべき時 Python

Python3 利回り キーワードは呼び出し元にジェネレーターを返し、ジェネレーターが反復されたときにのみコードの実行が開始されます。

A return 関数内では、関数の実行が終了し、単一の値が呼び出し元に返されます。

これは、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 キーワードを使用するとパフォーマンスが向上します。