天天看點

Python程式設計:generator生成器

清單生成器

# 清單生成式
lst = []
for i in range(10):
    lst.append(i * 2)
print(lst)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 相當于:
lst = [i * 2 for i in range(10)]
print(lst)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 清單生成器:循環疊代,推斷下一進制素
lst = (i * 2 for i in range(10))
print(lst)
# <generator object <genexpr> at 0x0000000004200CF0>

"""生成器:
隻用調用是才會生成相應的資料
隻記錄目前位置
隻有一個__next__()
"""      

yield生成器

# 菲波那切數列Fibonacci
def fib(max):  # 此時不能叫函數,應該叫生成器
    n = 0
    a, b = 0, 1
    while n < max:
        yield b  # 傳回目前值,并儲存目前狀态
        a, b = b, a+b  # 同時指派
        n = n+ 1
    return "異常消息"  # 輸出異常資訊

f = fib(10)
print("===")
print(f.__next__())  # 下一個值
print("===")
print(f.__next__())

print("==start loop==")
# for i in f:
#     print(i)
while True:
    try:
        g = next(f)
        print(g)
    except StopIteration as e:
        print("value of e :", e.value)
        break

"""OUT:
===
1
===
1
==start loop==
2
3
5
8
13
21
34
55
value of e : 異常消息
"""      

yield生成器-協程

import time

def consumer(name):  # 消費者
    print("%s 來吃包子了!" % name)
    while True:
        baozi = yield
        print("%s 吃了第 %s 個包子" % (name, baozi))

def producer():  #  生産者
    a = consumer("A")  #初始化一個生成器
    b = consumer("B")
    a.__next__()  #程式走到第一個yield
    b.__next__()
    print("我要開始做包子了")

    for i in range(10):
        time.sleep(1)
        print("第 %s 個包子" % i)
        a.send(i)  # 将資料發送到 yield 位置,并執行一次next
        b.send(i)

producer()
# consumer("a")

"""
A 來吃包子了!
B 來吃包子了!
我要開始做包子了
第 0 個包子
A 吃了第 0 個包子
B 吃了第 0 個包子
第 1 個包子
A 吃了第 1 個包子
B 吃了第 1 個包子
第 2 個包子
A 吃了第 2 個包子
B 吃了第 2 個包子
第 3 個包子
A 吃了第 3 個包子
B 吃了第 3 個包子
第 4 個包子
A 吃了第 4 個包子
B 吃了第 4 個包子
第 5 個包子
A 吃了第 5 個包子
B 吃了第 5 個包子
第 6 個包子
A 吃了第 6 個包子
B 吃了第 6 個包子
第 7 個包子
A 吃了第 7 個包子
B 吃了第 7 個包子
第 8 個包子
A 吃了第 8 個包子
B 吃了第 8 個包子
第 9 個包子
A 吃了第 9 個包子
B 吃了第 9 個包子
"""