生成器,推導式

一.生成器:python

生成器的實質就是迭代器app

在python中有三種方式獲取生成器:函數

1.經過生成器函數spa

2.經過各類推導式來實現生成器指針

3.經過數據的轉換也能夠獲取生成器code

二.經過生成器函數獲取生成器:對象

def func():
    print('哈哈')
    yield '呵呵'   #有yield就是生成器
ret = func() #經過函數來建立一個生成器即生成器函數被執行,獲取的是生成器,而不是函數的執行
print(ret) #返回的值是個地址就是個生成器
結果:<generator object func at 0x0000000000B99D00>

就是將函數中的return換成yield就是生成器,blog

return:直接返回結果,結束函數的調用內存

yield:返回結果,能夠讓函數分段執行.generator

1.如何執行生成器:

1)生成器的本質就是迭代器,因此能夠用__next__()進行執行

def func():
    print('周杰倫')
    yield '昆凌'
    print('哈哈')
    yield '呵呵'
ret = func()
print(ret.__next__())
print(ret.__next__())
結果:周杰倫
    昆凌
    哈哈
    呵呵

注意:若是最後一個yield執行完畢,再次__next__()程序會報錯

生成器的做用:省內存,能夠一次去一個,一個個的指向下一個,不會回去,__next__()到哪,指針就指哪,下一次繼續獲取指針指向的值.

2.用send()方法:

def eat():
    print('我吃什麼')
    a = yield '饅頭'
    print('a=',a)
    b = yield'大餅'
    print('b=',b)
    c = yield'韭菜盒子'              
    print('c=',c)
    yield 'GAME OVER'
gen = eat() #獲取生成器
print(gen.__next__())
print(gen.send('胡辣湯'))
print(gen.send('狗糧'))
print(gen.send('貓糧'))
結果:我吃什麼
饅頭
a= 胡辣湯
大餅
b= 狗糧
韭菜盒子
c= 貓糧
GAME OVER

send 和 __next__區別
1).send和next()都是讓生成器向下走一次

2).send能夠給上一個yield的位置傳遞值,不能給最後一個yield發送值,第一次執行生成器代碼的時候不能使用send()

3.生成器本質上是迭代器,因此能夠使用for循環取值

def func():
    print('哈哈')
    yield '呵呵'
    print('嘿嘿')
    yield '嘻嘻'
    print('呀呀')
    yield'花花'
ret = func()
for i in ret:
    print(i)

4.能夠用列表list取值:

def func():
    print('哈哈')
    yield '呵呵'
    print('嘿嘿')
    yield '嘻嘻'
    print('呀呀')
    yield'花花'
ret = func()
print(list(ret))
結果:哈哈
    嘿嘿
    呀呀
['呵呵', '嘻嘻', '花花']

三.列表推導式,生成器表達式以及其餘推導式

1)列表推導式:[結果 for 變量 in 可迭代對象 if 篩選]

例:給一個列表,經過循環,向列表中添加1-9

lst = []
for i in range(1,10)
    lst.append(i)
print(lst)

經過列表推導式:

lst = [i = for i in range(1,10)]
print(lst)

對列表中的數據進行篩選:[結果 for 變量 in 可迭代對象 if條件]

lst = [i fro i in range(1,101) if i%2 == 0]
print(lst)

2)生成器表達式:

生成器表達式和列表推導式的語法基本上同樣,只是把[]替換()

gen = (i for i in range(100))
print(gen)
結果:<generator object <genexpr> at 0x0000000000A29D00>

打印結果是個生成器,能夠用for循環來獲取最終結果

gen = (i for i in range(100))
for i in gen:
    print(i)

生成器表達式也能夠進行篩選,跟列表表達式同樣,只是[]變成了()

生成器表達式和列表推導式的區別:

1.列表推導式比較耗內存,一次性加載,生成器表達式幾乎不佔內存,使用的時候才分配和使用內存.

2.獲得的值不同,列表推導式獲得的是一個列表,生成器表達式獲取的是一個生成器

生成器的惰性機制:生成器只有在訪問的時候才取值,說白了,你找他要他纔給你值,不找他要,他就不回執行.

def func():
    print(111)
    yield 222
g = func() # 生成器g
g1 = (i for i in g) # 生成器g1. 可是g1的數據來源於g
g2 = (i for i in g1) # 生成器g2. 來源g1
print(list(g)) # 獲取g中的數據. 這時func()纔會被執行. 打印111.獲取到222. g完畢.
print(list(g1)) # 獲取g1中的數據. g1的數據來源是g. 可是g已經取完了. g1 也就沒有數據了
print(list(g2)) # 和g1同理

神坑:生成器,要值的時候纔拿值

3)字典推導式{結果 for 變量 in可迭代對象 if 篩選} 結果--->key:value

dic = {'a':'b','c':'d'}

把字典中的key和value互換

dic = {"a":"b", "c":"d"}
new_dic = {dic[key]:key for key in dic }
print(new_dic)

4)集合推導式:{結果 for 變量 in 可迭代對象 if 篩選}  結果--->key

集合推導式能夠直接生成一個集合,集合特別,無序,不重複,因此集合推導式自帶去重功能

lst = ["馬化騰", "馬化騰", "王建忠", "張建忠", "張建忠", "張雪峯", "張雪峯"]
s = {i for i in lst}    # 集合推倒式
print(s)

總結:推導式有:列表推導式,字典推導式,集合推導式,沒有元祖推導式

  生成器表達式:(結果 for 變量 in 可迭代對象 if 篩選)

  生成器表達式能夠直接獲取到生成器對象,生成器能夠直接進行for循環,生成器具備惰性機制

相關文章
相關標籤/搜索