迭代器 生成器

2022-07-24 02:51:11 字數 4588 閱讀 6943

迭代器:

可迭代物件:要遵守迭代協議,只要有__iter__方法的,就是可迭代物件,可以被for迴圈

迭代器:要遵守迭代器的協議,有__iter__和__next__方法的就叫迭代器

建立乙個迭代器 == 可迭代物件.__iter__()

使用迭代器,就是 == 迭代器.__next__()

lst = [1,2,3](三個獲取的都是1)

l1 = lst.__iter__().__next__()

l2 = lst.__iter__().__next__()l3 = lst.__iter__().__next__()    print(l1),print(l2),print(l3)都是1

那麼換一種方式呢?

lst = [1,2,3]

l1 = lst.__iter__()          從乙個可迭代物件轉化為迭代器

print(l1.__next__())

print(l1.__next__())

print(l1.__next__())          此時輸出的結果為1,2,3,如果繼續往下再加__next__(),就會報錯

輸出可迭代物件的記憶體位址

print(str.__iter__('你好'))      print(list.__iter__([1,2,3]))    print(dict.__iter__())    print(set.__iter__())     print(tuple.__iter__((1,2,3)))      print(range.__iter__(range(1,5)))   

生成器定義:

通俗來說,在函式體中存在yield就是生成器,函式名+小括號就產生了生成器,並且只能向下執行

函式體中的yield,就是辨別生成器和函式的依據

生成器的好處就是可以節省空間,一次性完成從上往下執行

那如何產生乙個生成器呢?

產生乙個生成器:

deffoo():

print(123)

yield 4

print(foo())      結果為,生成器foo的記憶體位址

print(foo)       函式foo的記憶體位址

那麼按照上面這個生成器來看,怎麼樣才能實現print(123)?

def

foo():

print(123)

yield 456f =foo()

print(f.__next__())    這樣就實現了print(123),並有返回值456

print(foo.__next__())   如果把f換成了foo(),就會一直生成新的生成器,會重複列印123,456

yield的作用:

yield也可以有返回值,同時也會記錄生成器執行到**,不會再繼續往下執行

yield可以指定返回值,沒有就是none

現在可以來試著捋一捋生成器的執行流程:

def

foo():             1,定義函式

print(123)          5,執行

yield 456           6,返回值456,停止往下執行

print(789)

yield 1111g =foo()             2,等號右邊foo()  3,將foo()賦值給g

print(g.__next__())       4,g.__next__()

當有大批量的資料時,用for迴圈就會佔大量的空間,那這時不妨用生成器

li =

deffunc():

for i in range(300):

print

(i)func()

print

(li)

deffunc():

for i in range(300):

yield i

g = func()

print(g.__next__())        隨取隨用,不會過多的開闢空間

print(next(g))            和g.__next__()效果一樣

yield和next的對應:

乙個.__next__()對應乙個yield,如果多了,就會報錯

def

func():

print(1)

yield 2

print(3)

yield 4

yield 5

yield 6g =func()

print

(next(g))

print

(next(g))

print

(next(g))

print(next(g))        最後乙個yield下面可以寫**,但是不會執行

send:傳送(在外界向生成器傳遞引數)

send == __next__ + 傳值(傳給上乙個yield停住的地方)

def

func():

print(44)

l = yield 5          send,將'哈哈'傳遞給l,

print(l)

yield 66g = func() #

生成乙個生成器

print(g.__next__

())print(g.send('

哈哈'))      輸出結果為:44,5,哈哈,66

再來乙個

def

func():

print(44)

l = yield 5

print(1)

yield 66g =func()

print(g.send(none))       輸出結果為:44,5

第一次啟動生成器的時候不能用send,但是可以用send(none),這時send的傳值功能就取消了,只保留next功能

所以,第一次啟動生成器的時候,  生成器.__next__()  或者  生成器.send(none)

yield from:

def

func():

lst = [1,2,3,4,5]

yield

from

lst      在這兒實現的就是for迴圈,for i in lst:print(i)

g =func()

print(g.__next__

())print(g.__next__

())print(g.__next__

())print(g.__next__

())print(g.__next__())      ps:yield from只能用next

推導式:推導式只能走乙個分支,但三元運算子可以實現多項

先寫結果,再寫語句,如果有篩選,在語句後面新增條件

列表:

推導式:

print([i for i in range(16)])

展開式:

li =

deffunc():

for i in range(16):

func()

print(li)

列表篩選:

推導式:

print([i for i in range(10) if i % 3 ==0])

展開式:

li =

deffunc():

for i in range(10):

if i % 3 ==0:

func()

print(li)

集合的推導式:

推導式:    

dic =

print() 結果是:(,)或()

篩選:

print()

集合的推導式和字典很像,但是它只是集合

字典:

推導式1:

lst1 = ['

1','2'

] lst2 = [2,3]

print() 輸出結果為

推導式2:

dic =

print()

生成器的推導式:

推導式:

l1 = (i for i in range(1000) 條件) print

(l1),生成器的位址

for i in range(10):

print(l1.__next__

())展開式:

deffunc():

for i in range(100):

if i % 3 ==0:

yield

i

g =func()

for n in range(10):

print(g.__next__())

生成器 迭代器

最近見天一直在看廖大的python教程,卻發現很多基礎看著很簡單,但卻不會應用,歸根結底還是因為理解不到位,故而又將教程學了一遍,並將自己的理解記錄一下,也方便後面查閱。由於沒有相關程式設計基礎,有些理解可能是錯的,敬請批評指正。想深入具體學習廖大部落格請移步廖雪峰的官方 有時候用迴圈生成列表太過繁...

迭代器,生成器

迭代器 生成器 生成器的第1種實現方式 列表生成式改為生成器 python中yield關鍵字 函式中如果有yield,那麼呼叫這個函式的返回值為生成器。當生成器g呼叫next方法,執行函式,知道遇到yield就停止 再執行next,從上一次停止的地方繼續執行 函式中遇return直接退出,不繼續執行...

迭代器 生成器

迭代器 iter 可迭代物件 下乙個元素的值 next 可迭代物件 類中實現 iter 方法 提供迭代器 實現迭代器 import time class mylistiter object 迭代器類 def init self,data self.data data self.index 0 def...