生成器函式,迭代器

Bound_w發表於2018-08-13

1.什麼是生成器?

  在python中,一邊迴圈,一邊計算的機制就是生成器。可以返回一個可迭代的物件,生成器本質上是一個迭代器,在一個簡單的函式中使用yield關鍵字,就可以生成一個簡單的生成器,那麼這個函式就稱為生成器函式。

return 和yield都會返回一個值,區別就在於yield會儲存當前的狀態,在返回後又回到當前的狀態繼續執行,而return會結束函式。

2.獲取生成器的三種方式

  • 通過生成器函式來獲取   將函式中的return換成yield就是生成器。
def func():
    print("111")
    yield 222
geener=func()#獲取到生成器
ret=geener.__next__()#函式開始執行,取值
print(ret)

那麼我們可以看到, yield和return的效果是一樣的. 有什麼區別呢? yield是分段來執行⼀個
函式. return呢? 直接停止執行函式。

def func():
print("111")
yield 222
print("333")
yield 444
gener = func()
ret = gener.__next__()
print(ret)
ret2 = gener.__next__()
print(ret2)

執行第三次的話就會報錯
ret3
= gener.__next__() # 最後一個yield執⾏完畢. 再次__next__()程式報錯, 也就是 說. 和return無關了。 print(ret3)
錯誤資訊:StopIteration
  • 通過各種推導式來實現生成器  
    1,列表推導式 [結果, for迴圈, 條件篩選]
    2,字典推導式 {k:v, for迴圈, 條件篩選}
    3,集合推導式 { k ,for迴圈,條件篩選]
  • 通過資料轉換獲取生成器

生成器的作用:


def cloth():
for el in range(0,10000):
yield "衣服"+str(el)
c=cloth()#獲取生成器
print(c.__next__())#開始執行函式,一次一次執行
print(c.__next__())
print(c.__next__())
print(c.__next__())
print(c.__next__())
print(c.__next__())

根據生成器的惰性特:

  他是一個一個向下指,需要多少就指多少,不會一次全部拿出來,節省記憶體 _next_指哪去哪

send和__next__()區別:

  • send和next()都是讓生成器向下走⼀次。
  • send可以給上⼀個yield的位置傳遞值, 不能給最後一個yield傳送值. 在第一次執行生
    成器程式碼的時候不能使⽤用send()

 生成器可以使用for迴圈來獲取內部的元素:

def user ():
    print("111")
    yield 222
    print("333")
    yield 444
    print("555")
    yield 666
gen = user()
for el in gen:
    print(el )

生成器表示式的語法:   [想要的結果,for迴圈,if判斷]

列表推導式
求0-100以內的偶數
lst=[el for el in range(1,100)if el% 2==0] print(lst)
列表推導式
求1-100以內能被3整除的數
gen=(el for el in range(1,100) if el %3==0)
for num in gen:
    print(num )

 

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

  • 列表推導式比較耗記憶體. ⼀次性載入. ⽣成器表示式幾乎不佔⽤記憶體. 使⽤的時候才分配和使用記憶體
  •  得到的值不⼀樣. 列表推導式得到的是一個列表.生成器表示式獲取的是一個生成器。

 面試題:

def func():
    print(111)
    yield 222
    yield 333
g = func()     #獲取生成器
g1 = (i for i in g)    #生成器
g2 = (i for i in g1)  #生成器
print(list(g2))  #   111 \n [222,333]  源頭,從源頭把資料拿走了
print(list(g1))  #  []  這裡執行的時候,源頭已經沒有資料
def add(a,b):       #求和
    return a+b
 
def test():         #生成器函式 0,1,2,3
    for i in range(4):
        yield i
g = test()          #獲取生成器
for n in [2,10]:   #到最後才放資料(惰性)
    g = (add(10,i)for i in g)
print(list(g))      # [20, 21, 22, 23]

什麼是迭代器?

  python本身是沒有迭代器這個類的,但是如果一個類中有__next__(),和__iter__()方法的話,我們可以把它看成一個迭代器類。

迭代器的特點?

  只能向前,不能向後,並且也不佔用記憶體,適合遍歷資料量比較大的資料。可以使用dir()方法來檢視是否可以執行  

相關文章