巨蟒python全棧開發-第12天 生成器函數 各類推導式 yield from

一.今日主要內容總覽(重點)python

1.生成器(目的:幫助咱們建立對象)
(1)生成器的本質就是迭代器
(2)一個一個的建立對象
(3)建立生成器的方式:
1.生成器函數
2.經過生成器表達式來獲取生成器
3.類型轉換(看不到)

2.生成器函數(重點)
(1)生成器函數中包含 yield關鍵字,返回數據和return差很少
return會當即結束和這個函數的執行
yield 能夠分段的執行一個函數

(2)大坑(五星重點):
  生成器函數在執行的時候返回生成器,而不是直接執行次函數

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

(4)全部的生成器都是迭代器,均可以直接使用for循環
均可以使用list()函數來獲取到生成器內全部的數據

(5)生成器中記錄的是代碼而不是函數的運行
def func():
print('個人天哪')

yield '寶寶'
gen=func() #建立生成器,此時運行會把生成器函數中的代碼記錄在內存
當執行到__next__(),運行此空間中的代碼,運行到yield結束

(6)生成器
優勢:節省內存,生成器自己就是代碼,幾乎不佔用內存
特色:惰性機制,只能向前,不能反覆

3.各類推導式(詭異)
列表推導式 [結果 for 循環 if]
字典推導式 {結果(k,v) for 循環 if}
集合推導式 {結果(k) for 循環 if}

4.生成器表達式(重點)
(結果 for循環 if)

二.今日內容大綱數組

1.生成器函數app

2.各類推導式函數

3.yield fromspa

三.內容詳解code

1.生成器函數對象

(1)blog

def func():
    print('我叫周潤發')
    return '林志玲'        #return
ret=func()
print('返回值是:',ret)
'''
結果:
我叫周潤發
返回值是: 林志玲
'''

(2)ip

注意:
函數中包含了yield,次函數就是生成器函數
大坑:生成器函數運行以後,產生一個生成器,而不是運行函數
def func():
    print('我叫周潤發')
    yield '林志玲'        #yield表示返回,不會終止函數的執行
    print('寶寶去幹嗎了???')
    yield '寶寶回來了'
    print('大冬瓜,你好')
    # yield '沒了'
ret=func()      #執行函數,可是此時沒有運行函數
#此時,咱們拿到的是生成器ret
print('返回值是:',ret)      #返回值是: <generator object func at 0x000002286D7CCF68>
#
# #執行到下一個yield
print(ret.__next__())       #第一次執行__next__此時函數纔開始執行
print(ret.__next__())       #第二次執行__next__此時函數纔開始執行,執行到下一個yield
#
# print(ret.__next__())     #若是最後一句沒有  ''yield '沒了' '',報錯緣由是:StopIteration
                            # 這句話開始報錯,而且'大冬瓜,你好'也不會打印

'''
結果:
返回值是: <generator object func at 0x000001B57FC2CF68>
我叫周潤發
林志玲
寶寶去幹嗎了???
寶寶回來了
'''

(2-1)內存

def func():
    print('我叫周潤發')
    yield '林志玲'        #yield表示返回,不會終止函數的執行
    print('寶寶去幹嗎了???')
    yield '寶寶回來了'
    print('大冬瓜,你好')
    yield '沒了'
ret=func()

#第一種
for i in ret:
    print(i)

#第二種
while 1:
    try:
        k=ret.__next__()
        print(k)
    except StopIteration:
        break

(3)

買衣服, JACK JONES 10000件衣服
當數據量很大,有用不了,怎麼辦,用一個拿一個

(3-1)直接放入列表中10000件
def buy():
    lst=[]
    for i in range(10000):
        lst.append("衣服%s"%i)
    return lst
k=buy()
print(k)

(3-2)取20件,簡單版本

def buy():
    for i in range(10000):
        yield '衣服%s' %i
lst=buy()           #生成器或者迭代器的好處:節省內存
# print(lst.__next__())
# print(lst.__next__())
# print(lst.__next__())
#
for i in range(20):
    print(lst.__next__())

(3-3)#想拿多少件拿多少件//重磅題目

def buy():
    for i in range(10000):
        yield '衣服%s' %i
re=buy()
while 1:
    n=input('請輸入須要提取的衣服數量:').strip()
    m=0
    for i in re:
        print(i)
        m += 1
        if m==int(n):
            break
    s=input('是否還要繼續取衣服:').strip()
    if s=='':continue
    else:break

(4)

def buy():
    for i in range(10000):
        yield '衣服%s' %i
lst=buy()

# 方法一:
for yifu in lst:    #迭代器.__next__()
    print(yifu)   #注意這裏是沒有加括號的 # 方法二:   #超級重點
print(lst)
lst=list(lst)   #將地址強轉成了列表裏的內容
print(lst)

(5)

(5-1)

def func():
    print('韭菜盒子')
    a=yield '韭菜雞蛋'
    print('a',a)
    b=yield '韭菜西紅柿'
    print('b',b)
    c=yield '火燒'
    print('c',c)
gen=func()
#
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
結果:
結果:
韭菜盒子
韭菜雞蛋
a None
韭菜西紅柿
b None
火燒

(5-2)

功能介紹
send() =>__next__()
send() 能夠給上一個yield傳值
def func():
    print('韭菜盒子')
    a=yield '韭菜雞蛋'
    print('a=',a)
    b=yield '韭菜西紅柿'
    print('b=',b)
    c=yield '火燒'
    print('c',c)
gen=func()

# # 方法一:
print(gen.__next__())    # 第一個位置用send沒有任何意義 #結果:
# 韭菜盒子
# 韭菜雞蛋
print(gen.send('籃球'))    # 給上一個yield位置傳值 #結果:
# a=籃球
# 韭菜西紅柿
print(gen.send('足球'))
#結果:
# b=足球
# 火燒
# print(gen.send('排球'))#這句話再傳入就會報錯了,由於後邊沒有接收了

(5-3)
def eat():
     print("我吃什麼啊")
     a = yield "饅頭"
     print("a=",a)
     b = yield "⼤餅"
     print("b=",b)
     c = yield "⾲菜盒⼦"
     print("c=",c)
     yield "GAME OVER"

gen = eat() # 獲取⽣成器

ret1 = gen.__next__()               #我吃什麼啊
print(ret1)                         #饅頭
ret2 = gen.send("胡辣湯")          #a= 胡辣湯
print(ret2)                         #⼤餅
ret3 = gen.send("狗糧")             #b= 狗糧
print(ret3)                         #⾲菜盒⼦
ret4 = gen.send("貓糧")             #c= 貓糧
print(ret4)                         #GAME OVER
 

2.各類推導式

(1)

#生成列表:python1期 =>python18期

lst=[]
for i in range(1,19):
    lst.append('python%s期'%i)
print(lst)

(2)

列表推導式語法: [結果 for循環 if 條件]

不要着急寫結果,先寫循環,再寫結果
lst=['python%s期'%i for i in range(1,19)]   #循環一次拿一次
print(lst)

'''
結果:
['python1期', 'python2期', 'python3期', 'python4期', 'python5期', 'python6期',
 'python7期', 'python8期', 'python9期', 'python10期', 'python11期', 'python12期', 
 'python13期', 'python14期', 'python15期', 'python16期', 'python17期', 'python18期']
'''

(3)練習

# 練習1 生成列表,相似於表中裝好的數據是 1-100之間全部的偶數的平方

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

# 練習二:篩選出列表中姓張的同窗,lst=['張無忌','吳奇隆','張詩詩','范冰冰','張翠山']
#法一
lst=['張無忌','吳奇隆','張詩詩','范冰冰','張翠山']
li=[i for i in lst if i[0]=='']
print(li)
#法二
li=[i for i in lst if i.startswith('')]
print(li)

# 練習三:尋找名字中帶有兩個e的人的名字

names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
        ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
li=[ii for i in names for ii in  i if ii.count('e')>=2]
print(li)
#老師寫法
li=[ii for i in names for ii in  i if ii.count('e')==2]
print(li)

(4)#字典推導式

# 語法: {結果(key:value) for循環 if條件}
lst=[11,22,33]      #結果{0:11,1:22,2:33}
dic={i:lst[i] for i in range(len(lst))}
print(dic)

# 練習: {"主食": "炒麪", "副食": "小拌菜", "湯":"疙瘩湯"}
# 把字典的key和value互換,生成新字典
dic={"主食": "炒麪", "副食": "小拌菜", "":"疙瘩湯"}
di={v:k for k,v in dic.items()}     #這個題目當時沒有想出來,不要受上一個題目影響
print(di)

(5)集合推導式

集合推導式{k for循環 if 條件}

沒有元組推導式
g=(i for i in range(10))    #生成器表達式是一次性的,若是想在迭代完,繼續用,再寫一遍
print(g)                  #<generator object <genexpr> at 0x0000000009E573B8>
print(g.__next__())     #執行10次取完,也就是再寫9次
print(g.__next__())     #第11次,StopIteration

(6)

#生成器函數
def func():
    print(111)
    yield 222
    # yield 333       #就算後邊有再多的yield ,也是放在第一個列表中
    # yield [1,2,3]

#注意:1.惰性機制,2.只能向前
g = func()          # 建立⽣成器g
g1 = (i for i in g) #生成器表達式  建立了一個新的⽣成器g1. 可是g1的數據來源於g
g = func()
g2 = (i for i in g1) # 建立了一個新的⽣成器⽣成器g2. 來源g1

#注意:在這以前,只是記錄了關係,並無工做

print(g)          #<generator object func at 0x0000013452C32048>
print(list(g)) # 獲取g中的數據. 這時func()纔會被執⾏. 打印111.獲取到222. g完畢.
# #list(g)直接拿沒了
#
# print(list(g1)) # 獲取g1中的數據. g1的數據來源是g. 可是g已經取完了. g1 也就沒有數據了
print(list(g2)) # 和g1同理
不管註釋,倒數第一行仍是註釋倒數第二行,結果都是下面結果
'''
結果:

<generator object func at 0x000002056A182048>
111
[222]
111
[222]

'''
若是都放開是
'''

<generator object func at 0x000002056A182048>
111
[222]
111
[222]

[]


'''

3.yield from

 (1)

def func():
    # lst=['衣服%s'%i for i in range(500)]
    # yield from lst      #將列表中的每一項進行yield返回

    for i in range(500):      #等價於上邊兩行,上邊至關於yield from中的列表中的一行
        yield '衣服%s'%i

gen=func()
print(gen.__next__())
print(gen.__next__())
'''
總結:
1.list=列表推導式
  yield from list
2.for 循環
  yield 值
1和2等價
'''

(2)先拿第一個,再拿第二個

def func():
    lst=['衣服%s'%i for i in range(2)]
    yield from lst

    lst = ['python%s' % i for i in range(15)]
    yield from lst
gen=func()
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
'''
結果:
衣服0
衣服1
python0
python1
python2
'''

今日做業:

2,用列表推導式作下列小題
(1)
(1)過濾掉長度小於3的字符串列表,並將剩下的轉換成大寫字母
'''
lis=['penchengchegn','wusir','sir','we']
li=[i.upper() for i in lis if len(i)>=3 ]
print(li)
'''

(2)

求(x,y)其中x是0-5之間的偶數,y是0-5之間的奇數組成的元祖列表
'''
li = [(x,x+1) for x  in  range(6) if x%2==0]

# 全排列,注意這個題目的寫法
li = [(x,y) for x  in  range(6) if x%2==0 for y in range(6) if y%2==1]
print(li)
'''

(3)

求M中3,6,9組成的列表M = [[1,2,3],[4,5,6],[7,8,9]]
M = [[1,2,3],[4,5,6],[7,8,9]]
li=[i[2] for i in M]
print(li)               # 結果:[3, 6, 9]

M = [[1,2,3],[4,5,6],[7,8,9]]
li=[[i for i in range(1,4)],[i for i in range(4,7)],[i for i in range(7,10)]]
print(li)               #結果:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

M = [[1,2,3],[4,5,6],[7,8,9]]
lst = [ a for i in M for a in i if a ==i[2]]
print(lst)

(4)

求出50之內能被3整除的數的平方,並放入到一個列表中。
'''
li=[i**2 for i in range(50) if i%3==0]
print(li)
'''

(5)

構建一個列表:['python1期', 'python2期', 'python3期', 'python4期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期']
'''
li=['python%s期'%i for i in range(1,11)]
print(li)
''')

(6)

構建一個列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
'''
li=[(x,x+1) for x in range(6)]
print(li)
'''

(7)

構建一個列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
'''
li=[i for i in range(19) if i%2==0]
print(li)
'''

(8)

有一個列表l1 = ['alex', 'WuSir', '老男孩', '太白']將其構形成這種列表['alex0', 'WuSir1', '老男孩2', '太白3']
l1 = ['alex', 'WuSir', '老男孩', '太白']
li=[l1[s]+str(s) for s in range(4)]
print(li)

(9)

題目

有如下數據類型:
x = {
    'name':'alex',
    'Values':[{'timestamp':1517991992.94,
         'values':100,},
        {'timestamp': 1517992000.94,
        'values': 200,},
        {'timestamp': 1517992014.94,
         'values': 300,},
        {'timestamp': 1517992744.94,
         'values': 350},
        {'timestamp': 1517992800.94,
         'values': 280}
        ],}
將上面的數據經過列表推導式轉換成下面的類型:
[[1517991992.94, 100], [1517992000.94, 200], [1517992014.94, 300], [1517992744.94, 350], [1517992800.94, 280]]

答案:

 

x = {
    'name':'alex',
    'Values':[{'timestamp':1517991992.94,
         'values':100,},
        {'timestamp': 1517992000.94,
        'values': 200,},
        {'timestamp': 1517992014.94,
         'values': 300,},
        {'timestamp': 1517992744.94,
         'values': 350},
        {'timestamp': 1517992800.94,
         'values': 280}
        ],}

li=[[i['timestamp'],i['values']] for i in x['Values']]
print(li)
相關文章
相關標籤/搜索