Python ジェネレーターの紹介

巴扎黑
巴扎黑オリジナル
2017-07-17 15:54:351561ブラウズ

私が Python を学ぶために Liao Xuefeng のブログをたどったとき、ジェネレーターの章を見たときに、最初に generator について言及しました。その後、情報を検索しているときに、この記事にこれらの概念がまとめられています。ジェネレータ

文字通り理解すると、これはジェネレータです。実装方法は 2 つあります:

1. リスト ジェネレータ ([]) とは異なりますが、() で表されます。 (これをジェネレータ式と呼ぶそうです(笑))

アクセス方法は、forループを使ってアクセスすることもできますし、.nextを使ってアクセスすることもできます。

N = ['Hello', 'World', 18, 'Apple', 'None']
hh = (s.lower() for s in N if isinstance(s,str) ==True)print hh#for item in hh:#    print item#print hh.next()#print hh.next()#print hh.next()#print hh.next()

出力結果
at 0x7f543a074690>

hello

world

apple
none

hhは、配列と同様にジェネレーターによって返される値です。 for ループ アクセスと .next() アクセスのサポート 注意すべき点は、ポインタが末尾に到達したときや、C++ のイテレータが末尾を指したときと同様に、for ループの実行後は hh.next() を実行できないことです。にアクセスするとエラーが発生します。

2. yield を使用して生成します (ジェネレーター関数と呼ばれます)

next() または for ループで呼び出されても、yield が実行された後は n の値が返され、その後現在の状態が一時停止されて返されます。 。

def create_counter(n):print "create counter"#while True:while False:yield nprint 'increment n'n += 1cnt = create_counter(2)#print cntfor item in cnt:print item#print next(cnt)#print next(cnt)#print cnt.next()#print cnt.next()

たとえば、この例では、cnt を出力するときに、
は、これがジェネレーターであることを示します。

Falseの場合、create counterのみが出力されます。

Trueの場合、forループを使用すると無限ループが発生します。

コルーチン:

プロセスとスレッドの概念があることは知っていますが、コルーチンが何であるかはよくわかりません

技術的な観点から見ると、「コルーチンは実行を一時停止できる関数です。」 。」 「発電機のようなもの」と理解すれば、あなたの考えは正しいです

。これを記事で見た。

Pythonの実行効率が高い理由

1. サブルーチンの切り替えはスレッド切り替えではなく、プログラム自体によって制御されるため、マルチスレッドに比べてスレッド切り替えのオーバーヘッドがありません。コルーチンのパフォーマンスが向上するという利点がより明らかです。

2. 実行プロセスにはロック機構がありません。

プロデューサーとコンシューマーの簡単な例を添付します:

def consumer():
    r = ''while True:
        n = yield rif not n:returnprint('[CONSUMER] Consuming %s...' % n)
        time.sleep(1)
        r = '200 OK'def produce(c):
    c.next()
    n = 0while n < 5:
        n = n + 1print('[PRODUCER] Producing %s...' % n)
        r = c.send(n)print('[PRODUCER] Consumer return: %s' % r)
    c.close()if __name__=='__main__':
    c = consumer()
    produce(c)

1. コンシューマー関数はジェネレーターです。
2. c.send(None) は、実際には next(c) と同等です。初めて実行されるときは、n = yield r になるまで実行され、その後停止され、r の値が呼び出し元に返されます。
3. yield r は send(msg) によって割り当てられる式であり、send(msg) には戻り値があります: 次の yield r 式のパラメーターです。
4. プロデュースが何かを生成したら、c.send(n) を通じてコン​​シューマ実行に切り替えます。コンシューマは、yield を通じてメッセージを取得し、それを処理し、yield を通じて結果を送り返します。つまり、c.send(1) は c にデータを送信するだけでなく、次の yield が c からデータを返すのを待ちます。これには戻り値があり、1 回のパスだけで完了します。返されたデータ (200 OK) は引き続き実行されます。
5. プロセス全体はロックフリーで、プロデューサーとコンシューマーが協力してタスクを完了するため、スレッドのプリエンプティブ マルチタスクではなく「コルーチン」と呼ばれます。

要約すると、 yield r は c.send を通じて値が割り当てられる式であり、戻り値は yield r 式の次のパラメーターになります。






以上がPython ジェネレーターの紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。