python學習筆記 生成器,迭代器,協程定義

2021-08-10 16:26:57 字數 4007 閱讀 7962

知識點:生成器就是通過封裝的演算法進行邊迴圈邊計算的機制,通過next()方法可以每次取乙個計算的值,也就是yield b 這個b是多少(x = next(generator) 這個x就是取到的b)。x = yield,那麼x 就是用於接收外部發來的值(generator.send(5),那麼x就是5)。

通過列表生成式我們可以取得想要的值,但是如果我們建立了乙個包含了百萬個值的列表,而只要取前面的幾個值,顯然這造成了記憶體和時間的浪費。此時,如果我們能用某種方法來把我們想要的值迴圈計算出來,那麼這無疑解決了上面的問題。這種通過某種演算法進行邊迴圈邊計算的功能,稱作生成器。

建立乙個生成器的方法有

>>> g1 = (x for x in range(5))

>>> next(g1) # 通過 next(g1) 或者 g1.send(none) 或者 g1,__next__() 啟動生成器 (next(g1) == g1.send(none))

0>>> next(g1) # 再通過next(g1) g1.send(none) 就可以取得下乙個值或者 g1.send(5)

1>>> g1.send(4)

2>>> list(g1) # 一次性取出剩下的值

[3, 4]

>>> next(g1)

traceback (most recent call last):

file "", line 1, in

stopiteration

當然,重新建立乙個生成器g1,我們可以直接用for迴圈進行迭代取值

>>> g1 = (x for x in range(5))

>>> for i in g1:

... print(i)

...012

34

def

fib(max):

n, a, b = 0, 0, 1

print('aaa')

while n < max:

print(b)

a, b = b, a + b

n = n + 1

print('a')

>>>fib(6)

aaa112

358a

我們說過生成器儲存的是演算法,如果這個演算法封裝在函式裡,那我們如何將這個函式變成生成器呢? 將yield放在迴圈中就可以實現。yield可以接收外部傳送的值(消費者生產者模式就是利用這個特性),還可以用於生成函式內部迭代的值

(1) yield用於生成函式內部迭代的值

def

fib(max):

n, a, b = 0, 0, 1

print('aaa')

while n < max:

yield b

a, b = b, a + b

n = n + 1

print('a')

>>> g = fib(5)

>>>

for i in g:

... print(i)

...aaa11

235a

函式的生成器也可以用next啟動,取值

>>> g = fib(5)

>>> next(g) # 解析:啟動生成器,程式執行到yield處等待,接下來yield就可以用於接收值(下面會有生產者消費者模式)。以後每次next都會迴圈一次while語句

aaa1

>>> next(g)

1>>> next(g)

2>>> next(g)

3>>> g.send(5)

5

(2)yield可以接收外部傳送的值(生產者消費者模式)

def

consumer

(name):

weikou = 0

while weikou < 10:

egg = yield

print("%s 在吃 egg [%s]" % (name,egg))

weikou += 1

c = consumer('tom')

next(c) # 此處等待接收

c.send(1) # tom 在吃 egg [1]

c.send(2) # tom 在吃 egg [2]

defproducer

(): c1 = consumer("tom")

c2 = consumer("john")

c1.__next__()

c2.send(none)

for i in range(3):

c1.send(i)

c2.send(i)

p = producer()

out-------------

tom 在吃 egg [1]

tom 在吃 egg [2]

tom 在吃 egg [0]

john 在吃 egg [0]

tom 在吃 egg [1]

john 在吃 egg [1]

tom 在吃 egg [2]

john 在吃 egg [2]

通過佇列的生產者消費者模式

上面這段**是最簡單的單執行緒下的並行的例子,也即協程,能同時進行多個任務。例子中就是2個消費者在同時吃包子,如果不用生成器的話,那麼就需要等到乙個人吃完了包子,另乙個人再吃。

用於for迴圈的資料型別有2類。

1.集合資料型別 list,dict,tuple,set,str…

2.generator。包括生成器和帶yield的generator function

只要是可以用for迴圈,那他就是可迭代物件(iterable)。

>>> 

from collections import iterable

>>> isinstance(,iterable)

true

>>> isinstance([1,2,3],iterable)

true

>>> isinstance((),iterable)

true

>>> isinstance({},iterable)

true

>>> isinstance((x for x in range(10)),iterable)

true

而像生成器這種還能用next()不斷呼叫取值的就是迭代器。而集合資料型別的就不是迭代器

>>> 

from collections import iterator

>>> isinstance(,iterator)

false

>>> isinstance((x for x in range(10)),iterator)

true

如果想把集合資料型別轉為迭代器,可以用iter方法進行轉換

>>> isinstance(iter(),iterator)

true

其實python的for迴圈本質上也是用next()呼叫的。

for i in [1,2,3,4,5]:

print(i)

#等價於

it = iter([1,2,3,4,5])

while

true:

try:

x = next(it)

print(x)

except stopiteration as e:

break

協程定義

1.必須在只有乙個單執行緒裡實現併發

2.修改共享資料不需加鎖

3.使用者程式裡自己儲存多個控制流的上下文棧

4.乙個協程遇到io操作自動切換到其它協程

根據協程定義,上面的寫的生產者消費者模型並不屬於嚴格意義上的協程,因為並沒有進行io操作

Python筆記 迭代器 生成器

1.什麼叫迭代?使用for迴圈遍歷取值的過程,叫做迭代 2.什麼是可迭代物件?能夠使用for遍歷取值的物件,叫可迭代物件 可迭代物件 str list set tuple dict 不可迭代物件 int float class 3.什麼是迭代器?迭代器是乙個可以記住遍歷的位置的物件 迭代器物件從集合...

Python學習筆記 生成器與迭代器

首先從一段 來簡單看下什麼是生成器 生成器與列表不同,生成器不會靜態地在記憶體中建立元素,它有點類似於函式,只輸出結果而不建立結果。想要檢視生成器輸出的所有元素,使用for迴圈 for item in g print item 取前n個元素 for i in range 10 print g.nex...

Python生成器和迭代器學習筆記

有時指上述的函式 一種實現了無引數 next 方法和 iter 方法的物件 例項 python內建的一種類,其繼承自collections.iterable py3.4 實現了 iter 或 getitem 方法的物件 class generatorsampleinclass def iter se...