python反復器とジェネレータ

13304 ワード

python反復器とジェネレータ
python反復器
なぜこのドキュメントを書くのか、自分がこんなに長い間pythonを学んだような気がして、無駄に勉強したような気がして、ずっとC++の考えでpythonコードを見ていて、基礎が全然マスターしていないので、混乱しています.
for(int i=0;i<100;i++)
	cout<<i<<endl;
for i in range(0,100)
	print(i)

C++では、forループは、まずi=0を実行し、その後、i<100、ループ中の文、i++を比較する間に判断が満たされないまで繰り返す.pythonのforループでは、rangeは反復器を返します.ループは以下の手順に理解できます.まず、rangeはリストを生成し、rangeは__を通過する.iter__関数は、これらのデータを反復器に変換し、forループのたびに__を実行します.next__関数は中のデータを呼び出し、配列にアクセスして最後にデータがない場合、StopIterationがポップアップされ、反復が終了します.もう少し加えると、確かにrangeだけでなく、for inという文は対応する反復器を抽出するはずです.以下のコードのように、rangeがなくても、forループを実現することができます.pythonの文法的包容性かもしれません.具体的なpythonがこれらの世代コードをコンパイルする基礎はまだ学んでいません.後でドキュメントを書くかもしれません.
#     
L = [1,2,3,4,5]
for element in L:
    print(str(element) * 3)
#      
S = 'PYTHON'
for s in S:
	print(s * 3)
#     
L = (1,2,3,4,5)
for element in L:
    print(str(element) * 3)
#     
G = {'Ruo', 'Data', 'Python'}
for g in G:
    print(g)
#     
for line in open('ex.txt'):
    print(line, end='')

これがpythonとC++forループの違いです.
ビルダー
反復器について述べ,pythonジェネレータの概念を引用する.
def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
        yield a
        
def main():
	for val in fib(20):
	    print(val)
	    
if __name__ == '__main__':
	main()

この関数の戻りはreturnではなくyieldを使用します.この2つの違いは何ですか.returnを使用して上記のコードを完成すれば、そうです.
def fib(n):
	a, b = 0, 1
	for _ in range(n):
		a, b = b, a + b
	return a
def main():
	for val in range(20):
		print(fib(val))

多くの人がこのコードを書いたのではないかと思いますが、次のコードは全部でa,b=b,a+b 210回実行され、yieldのコードは20回しか実行されていないことがわかります.ps:forループをmain関数に直接書けばいいのではないか、printをfibに書けばいいのではないかと言う人もいます.しかし,本論文では関数におけるreturnとyieldの違いについて議論し,あら捜しをしないでください.
それから私たちはyieldについて話して、yieldは生成器から離れられないと言って、yieldを含む関数は本質的にそれを1つの関数と見なすことができなくて、それは1つの生成器です.ジェネレータは特殊な反復器であり、なぜ私が最初に反復器を話す必要があるのか.前の小さい結び目の中の反復器、毎回__に従いますnext__メソッドは次のデータを順次生成するため、現在のステータスを保存する必要があります.これらの操作を実現するには、より強力な構文で実現することができます.ジェネレータです.
L = [ x*2 for x in range(5)]  #      
print(L)    # [0, 2, 4, 6, 8]  
G = ( x*2 for x in range(5))	#    
print(G)  
#  at 0x7f43c0818780>
#          python3  python2 next()   
print(G.__next__())  #    0
print(G.__next__())  #    2

もちろん、私たちは普通ジェネレータを建てて止まらないことはありません.next__()私たちは一般的にforループ、または関数反復に使用し、今そのfibnaci関数に戻ります.yieldを含む関数、すなわちジェネレータ自体には、現在実行されている状態を記録する機能が含まれており、ジェネレータに再アクセスすると、ジェネレータが反復を停止するまで元の状態から実行が続行されます.上のコードでは、forループが一時停止するたびに、次はジェネレータに入ってループを継続し、ループが終了するまでps:python 3ジェネレータにreturnを追加することができ、ジェネレータがreturnに遭遇すると、現在のジェネレータは終了します.
def fib(n):
	a, b = 0, 1
	for _ in range(n):
		a, b = b, a + b
		yield a
		return a
def main():
	for val in fib(20):
		print(val)
if __name__ == '__main__':
	main()
#        1