1.ジェネレータ#基本的にイテレータ
1.1発電機を内蔵しています
ジェネレータを作成するためのPythonで3つの方法があります。
1.ファンクション・ジェネレータ
2.ジェネレータの導出
組み込み関数またはモジュール3.python
1.2ジェネレータ機能
私たちは、最初のジェネレータ関数によって生成された建物を調べます。
def func():
print(11)
return 22
ret = func()
print(ret)
# 运行结果:
11
22
収量への復帰の機能、それはFUNC機能ではないようではなく、ファンクション・ジェネレータ
def func():
print(11)
yield 22
私たちは、理由である、任意の変更を書き込みませんでした?のは、カッコ内の関数名を取得したか見てみましょうか?
def func():
print(11)
yield 22
ret = func()
print(ret)
# 运行结果:
<generator object func at 0x000001A575163888>
私たちは関数本体のコードの関数を呼び出すと、キーワード歩留まりのとき実行実行され、我々はビルダーを宣言したいことを見つけられるだろう。Builderプログラムは、私たちにリターンを得られます
Builderは、本質的にイテレータイテレータの値は、どのように発電機を評価する方法。したがって、我々は、直接実行することができる次へ()または** _ _ _ _次の() ** ジェネレータ以下の方法
def func():
print("111")
yield 222
gener = func() # 这个时候函数不会执⾏. 而是获取到生成器
ret = next(gener) # 这个时候函数才会执行 推荐使用next()
#ret = gener.__next__() # 这个时候函数才会执行
print(ret) # 并且yield会将func生产出来的数据 222 给了 ret。
结果:
111
222
そして、私のジェネレータ関数は、より多くの収率で書き込むことができます。
def func():
print(11)
yield 22
print(33)
yield 44
print(func().__next__()) #启动了一个生成器
print(func().__next__()) #启动了另一个生成器
# 运行结果:
11
22
11
22
def func():
print("111")
yield 222
print("333")
yield 444
gener = func()
ret = gener.__next__()
print(ret)
ret2 = gener.__next__()
print(ret2)
ret3 = gener.__next__()
# 最后⼀个yield执⾏完毕. 再次__next__()程序报错 StopIteration异常
print(ret3)
プログラムは、収量の最後に実行されている場合、それは後ろに実行を継続次にイテレータのように、次、次の収率の数を超え、エラーう収率に相当する、()プログラムを説明します。
収量との違いを返します。
一般的にはリターン機能は一つだけ、彼の役割は、機能を終了することで、機能の実行の戻り値に提供されます。
複数設けられていてもよいジェネレータ関数を得て、彼は機能を停止しないことを、次の対応する捕捉要素が生成もたらします。
シナリオ:
私たちは、この需要を見て:ボス階下蒸しパンを販売歳の少年は、包子プルトニウムの上司は非常に現実的である万個のパンを命じ、彼らが働いたすべてのだろう。
def eat():
lst = []
for i in range(1,10000):
lst.append('包子'+str(i))
return lst
e = eat()
print(e)
そうすることは問題ありませんが、学生はそんなに、約2000、および8000の残りの部分を食べるので、我々はなかった、我々は唯一のいくつかの領域を達成することができ、脇に置きます。包子プルトニウムのボス効率が十分に高い場合、私は、あなたが、それはあまりにも多くのストレージスペースを取るし、完璧ではないでしょうかパンをパンを食べます。
def eat():
for i in range(1,10000):
yield '包子'+str(i)
e = eat()
for i in range(200):
next(e)
2間のこの違い:
最初は、全てのパンに直接それを行うメモリを取ることです。
第二は、非常に省メモリを生産食べることですが、また、以前の位置を保持します。
def eat():
for i in range(1,10000):
yield '包子'+str(i)
e = eat()
for i in range(200):
next(e)
for i in range(300):
next(e)
# 多次next包子的号码是按照顺序记录的。
1.3 sendメソッド(理解)
次に我々は、物事の新しい理解に来て、メソッドを送ります
# next只能获取yield生成的值,但是不能传递值。
def gen(name):
print(f'{name} ready to eat')
while 1:
food = yield
print(f'{name} start to eat {food}')
g = gen('alex')
next(g)
next(g)
next(g)
# 而使用send这个方法是可以的。
def gen(name):
print(f'{name} ready to eat')
while 1:
food = yield 222
print(f'{name} start to eat {food}')
g = gen('alex')
next(g) # 第一次必须用next让指针停留在第一个yield后面
# 与next一样,可以获取到yield的值
ret = g.send('骨头')
print(ret)
结果:
alex ready to eat
alex start to eat 骨头
222
def gen(name):
print(f'{name} ready to eat')
while 1:
food = yield
print(f'{name} start to eat {food}')
g = gen('alex')
next(g)
# 还可以给上一个yield发送值
g.send('骨头')
g.send('狗粮')
g.send('香肠')
違いを送信し、次の():
同じポイント:
発電機は一度下方対応を得ることができるように送信し、次の()。
降伏値が生成され得ることができます。
違い:
第1の取得収率値は、次の((なし)を送信することができない)送信することはできません使用することができます。
設定値が送信され得るために送信することができます。
から1.4利回り
python3であってもよく、データオブジェクトの直接各反復を提供する結果、発電機として返されます
# 对比yield 与 yield from
def func():
lst = ['卫龙','老冰棍','北冰洋','牛羊配']
yield lst
g = func()
print(g)
print(next(g)) # 只是返回一个列表
结果:
<generator object func at 0x0000018C18AB94F8>
['卫龙', '老冰棍', '北冰洋', '牛羊配']
def func():
lst = ['卫龙','老冰棍','北冰洋','牛羊配']
yield from lst
g = func()
print(g)
# 他会将这个可迭代对象(列表)的每个元素当成迭代器的每个结果进行返回。
print(next(g))
print(next(g))
print(next(g))
print(next(g))
结果:
<generator object func at 0x00000213E7D194F8>
卫龙
老冰棍
北冰洋
牛羊配
'''
yield from ['卫龙','老冰棍','北冰洋','牛羊配']
等同于:
yield '卫龙'
yield '老冰棍'
yield '北冰洋'
yield '牛羊配'
ピットから1.5利回り
def func():
lst1 = ['卫龙', '老冰棍', '北冰洋', '牛羊配']
lst2 = ['馒头', '花卷', '豆包', '大饼']
yield from lst1
yield from lst2
g = func()
for i in g:
print(i)
结果:
卫龙
老冰棍
北冰洋
牛羊配
馒头
花卷
豆包
大饼