python生成器和各種推導式

沐小熊發表於2018-12-11

一. 生成器
本質就是迭代器.
一個一個的建立物件
建立生成器的方式:
1. 生成器函式
2. 通過生成器表示式來獲取生成器
3. 型別轉換(看不到)

 

二. 生成器函式 (重點)
生成器函式中包含 yield , 返回資料和return差不多.
return會立即結束這個函式的執行
yield 可以分段的執行一個函式

生成器函式在執行的時候返回生成器. 而不是直接執行此函式

能向下執行的兩個條件:
__next__(), 執行到下一個yield
send(), 執行到下一個yield, 給上一個yield位置傳值

所有的生成器都是迭代器都可以直接使用for迴圈
都可以使用list()函式來獲取到生成器內所有的資料

生成器中記錄的是程式碼而不是函式的執行
def func():
print(“我的天哪 “)

yield “寶寶”

gen = func() # 建立生成器. 此時執行會把生成器函式中的程式碼記錄在記憶體
當執行到__next__(), 執行此空間中的程式碼, 執行到yield結束.

優點: 節省記憶體, 生成器本身就是程式碼. 幾乎不佔用記憶體
特點: 惰性機制, 只能向前. 不能反覆

 1 def func():
 2     print(`我叫周潤發`)
 3     yield `林志玲`  # yield表示返回. 不會終止函式的執行
 4     print(`我幹嘛了?`)
 5     yield `寶寶回來了`
 6     print(`寶寶你在幹嘛`)
 7     yield `沒了`
 8 ret = func()  # 執行函式,此時沒有執行函式
 9 # 此時我們拿到的是生成器
10 print(`返回值是`, ret)  #<generator生成器 object func at 0x0000018DAC980EB8>
11 
12 # 執行到下一個yield
13 print(ret.__next__())  #第一次執行到__next__此時函式才開始執行
14 print(ret.__next__())  #執行到下一個yield
15 print(ret.__next__())  # StopIteration

 

.各種推導式 (詭異)

列表推導式 [結果 for迴圈 if]

1 lst = [`python%s期` % i for i in range(1, 19)]
2 print(lst)

字典推導式 {結果(k:v) for迴圈 if}

 

1 dic = {"主食": "炒麵", "副食": "小拌菜", "": "疙瘩湯"}
2 dic1 = {v: k for k, v in dic.items()}
3 print(dic1)

集合推導式 {結果(k) for迴圈 if}

 

生成器表示式

 

 1 g = (i for i in range(10))  # 生成器表示式
 2 
 3 print(g)  # <generator object <genexpr> at 0x000001C354050EB8>
 4 
 5 print(g.__next__())  # 0
 6 print(g.__next__())  # 1
 7 print(g.__next__())  # 2
 8 print(g.__next__())  # 3
 9 print(g.__next__())  # 4
10 print(g.__next__())  # 5
11 print(g.__next__())  # 6
12 print(g.__next__())  # 7
13 print(g.__next__())  # 8
14 print(g.__next__())  # 9

 

 

四.yield from

def func():
    lst = [`衣服%s` %i for i in range(500)]
    yield from lst  # 可以吧一個可迭代物件

gen = func()
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())

 

相關文章