day14 生成函數的進階

1、上節回顧:python

一、可迭代對象:惰性運算          擁有__iter__方法面試

二、迭代器:                              擁有__iter__和__next__方法app

三、生成器:惰性運算,開發者自定義   本質:迭代器 因此擁有__iter__和__next__方法ide

     惰性運算:不取值就不計算  且每個值只能被取一次,取完爲止函數

     生成器的優勢:延遲計算,一次返回一個結果,也就是說,它不會一次生成全部的結果,這對於大數據處理很是有用大數據

生成器------迭代器:節省內存spa

1)生成器函數:3d

   帶有yield 關鍵字code

   執行函數以後的返回值是生成器,函數內的代碼並不會真正執行對象

   想讓生成器吐出數據,須要使用next 方法,send, for循環

2、新內容

一、生成器的調用例子 取用:cloth

def cloth():
    for i in range(100):
        yield "衣服%s"%i
g=cloth()
# 方法一
# for i in g:
#     print(i)
# 方法二
for i in range(100):
    print(g.__next__())
cloth

 

二、監聽文件末尾追加的例子

調用生成器並不執行,當取用的時候纔會執行def下面的內容(Windows系統的時候纔可使用)

def tail():
    f=open("你好.bak","r",encoding="utf-8")
    f.seek(0,2)
    while True:
        line=f.readline()
        if line:
            yield line
        import time
        time.sleep(0.1)
g=tail()
for i in g:
    print(i.strip())
生成器(監聽文件)

三、send  和next 的範圍是同樣的

     (1)從哪個yield開始接着執行,就把一個值傳給了那個yield

    (2)send 不能用在第一個觸發生成器,觸發生成器第一個必須是__next__()

     (3)生成器函數中有多少個yield就必須有多少個next+send

def func():
    print("*"*10)
    a=yield 5
    print(a)
    yield  10
g=func()
num=g.__next__()
print(num)
num2=g.send("alex")
print(num2)
# **********
# 5
# alex
# 10
send 例子
def averager():
    total=0.0
    count=0
    average=None
    while True:
        term=yield  average
        total+=term
        count+=1
        average=total/count
g_avg=averager()
g_avg.__next__()
print(g_avg.send(10))
print(g_avg.send(20))
print(g_avg.send(30))
# 10.0
# 15.0
# 20.0
利用 send(銀行七日化利息)

四、補充:python3 以後有的這個功能:yield from a

def func():
    a="AB"
    b="CD"
    yield from a
    #for i in a:yield i
    yield from b
    #for i in b:yield i
g_func=func()
for i in g_func:
    print(i)
yield from 的使用

五、觸發執行的方式

(1)生成器.__next__()

 (2)生成器.send()        

      send(None)==__next__().  

      send在next的基礎上傳一個值到生成器函數的內部

      send 操做不能用在生成器使用的第一次

      以上兩個執行幾回拿幾個數據,可能會遇到取完報錯

(3)for循環   每次取一個,取完爲止。for循環不會報錯

六、總結:

    生成器函數:生成一個生成器的函數

    生成器的本質:參數迭代器

    生成器函數的特色:(1)帶有yield 關鍵字 (2)且調用以後,函數內的代碼不執行

 觸發執行的方式:(1)next  (2)send  (3)for 循環

3、各類推導式

 一、列表推導式:

y=[1,2,3,4,5,6,7]
# 方法一
# x=[]
# for i in y:
#     x.append(i**2)
# print(x)
# 方法二
x=[i**2 for i in y]
print(x)
# [1, 4, 9, 16, 25, 36, 49]
列表推導式1
# x=[]
# for i in range(100):
#     x.append(i/2)
# print(x)
x=[i/2 for i in range(100)]
print(x)
列表推導式2

二、生成器表達式 (生成器表達式+for循環節省內存 推薦使用)

#列表推導式
y=[1,2,3,4,5,6]
x=[i**2 for i in y]  #[  ]
print(x)
#生成器表達式
y=[1,2,3,4,5,6]
g=(i**2 for i in y)  #(  )
print(g)
for i in g:
    print(i)
列表推導式和生成器表達式
l=["雞蛋%s"%i for i in range(10)]
print(l)
lmuji=("雞蛋%s"%i for i in range(10))
for egg in lmuji :
    print(egg)
雞蛋和母雞的理論

 三、補充:

並非全部的均可以轉換

g.__next__()==next(g )
g.__iter__()==inter(g)

四、30之內能被3整除的數的平方 列表推導式的例子

# 30之內能被3整除的數的平方
# x=[i**2 for i in range(30) if i%3==0]
# print(x)
def square(x):
    return  x**2
x=[square(i) for i in range(30) if i%3==0]
print(x)
30之內能被3整除的數的平方

五、字典推導式

dic={"a":10,"b":34}
dic_fre={dic[k]:k for k in dic}
print(dic_fre)
#{10: 'a', 34: 'b'}   key value 對換
key value 對換
mcase={"a":10,"b":34,"A":7,"Z":3}
mcase_frequency={k.lower():mcase.get(k.lower(),0)+mcase.get(k.upper(),0)for k in mcase}
print(mcase_frequency)
#{'a': 17, 'b': 34, 'z': 3}
字典中大小寫相加

六、集合的推導式 去重

squared={x**2 for x in [1,-1,2]}
print(squared)
#set([1,4])
集合的去重

 

 

面試題:

相關文章
相關標籤/搜索