1. 程式人生 > >十四:生成器函數和叠代器函數

十四:生成器函數和叠代器函數

generator example 技術分享 foo 數列 pri lis () 什麽是

一:列表生成器:就是在列表內部使用一條語句來生成一個列表。

example 1: 列表生成器示例

 1 # 列表生成: 把可叠代對象中的每一個元素進行操作的結果放在列表中
 2 
 3 s = [x * x for x in range(5)]
 4 
 5 
 6 # 操作也可以是一個函數
 7 
 8 def f(x):
 9     return x * x
10 
11 s = [f(x) for x in range(5)]

二:生成器函數:生成器函數與一般的函數有一個顯著的不同,對於一般的函數,會把所有的結果一次性返回,被存儲到內存中,對於數據量比較大的結果如果一次性全部返回會占用非常大的內存空間;但是生成器只是返回一個生成器對象,如果想要返回結果,只能調用內部的 next()方法進行操作,並且每次只能返回一個結果,對於大量的 next()操作可以使用 for 循環來實現。

example 2: 列表生成器創建生成器

1 s = (x * 2 for x in range(10))
2 print(s)    # <generator object <genexpr> at 0x00EEEA50>
3 
4 for i in s: # 生成器是一個可叠代對象
5     print(i)
6 
7 print(next(s))   # 等價於 s.__next__() in py2

三:生成器的創建:創建一個生成器有兩種方式,一種就是利用列表生成式來創建一個元祖,這個元祖就是一個生成器;另外一種方式就是使用yield來創建一個生成器。

example 3:yield 創建生成器示例:

 1 # 生成器的創建方式:yield 關鍵字實現
 2 
 3 # def foo():   # 生成器函數
 4 #     print(‘ok‘)
 5 #     yield 1     # 類似於一般函數的 return ,返回值為 1,下次從這個斷點開始往下執行
 6 #     print(‘ok2‘)
 7 #     yield 2
 8 #
 9 # f = foo()   # f 是一個生成器
10 # print(f)
11 #
12 # for i in f :  #生成器本身就是一個可叠代對象
13 #     print(i)   # 內存中始終只存儲有一個元素,py垃圾回收機制

四:可叠代對象:就是內部有 iter() 方法的對象,比如,列表,元祖,字典,都是可叠代對象。

example 4: 可叠代對象

1 # 什麽是可叠代對象? 內部有iter方法,列表,元祖,字典都是可叠代對象
2 
3 L= [1,2,3]
4 
5 L.__iter__()

五:利用 yield 來實現斐波那契數列,每個元素一個一個生成,並不是一下子都執行出來存放在內存中

example 5: 利用yield 來實現 斐波那契數列

技術分享圖片
 1 # 斐波那契數列:0 1 1 2 3 5 8 13
 2 
 3 # def fib(max):
 4 #     n,befor,after = (0,0,1)
 5 #     while n<max:
 6 #         yield befor     # 通過調用 next()一個一個的返回
 7 #         befor,after = after,befor + after
 8 #         n += 1
 9 #
10 # f = fib(8)
11 # print(f)
12 
13 # print(next(f))   # 0
14 # print(next(f))   # 1
15 # print(next(f))   # 1
yield 實現 Fib 數列

六:生成器中的傳值操作:send():可以利用該函數傳入值,即把該值傳送給 yield 的值

example 6:生成器傳值

 1 def bar():
 2     print(ok1)
 3     count = yield 1
 4     print(count)
 5 
 6     yield 2
 7 
 8 f = bar()
 9 print(f)
10 
11 next(f)  # 打印 ok1, yield返回
12 # s = f.send(None)  # 第一次send 只能傳入None ,等同於 next(f)
13 ret = f.send(eee)   # 把‘eee’發送到上次斷點處,賦值給 count ,然後打印
14 print(ret)   # 將整個生成器函數的返回值 返回給調用者,賦值給 ret

七:叠代器:生成器都是叠代器,叠代器不一定都是生成器。可叠代對象通過內置的 iter() 方法可以轉化為一個叠代器。叠代器同樣可以通過調用 next()方法。

1 # 生成器都是叠代器,叠代器不一定是生成器
2 
3 L= [1,2,3,4]
4 d = iter(L)
5 print(d)   # <list_iterator object at 0x017873F0>
6 
7 print(next(d))  # 1
8 
9 for i in [1,2,3]:  # 1,調用可叠代對象的 iter 方法 返回一個叠代器對象,2,不斷調用叠代器對象的 next 方法 3,處理Iterorstop異常

十四:生成器函數和叠代器函數