生成器是特殊的迭代器,這可能是因為無論是迭代器,或者是生成器,都可以被for迭代,但是他們又不太像。
my_generator = (i for i in range(3))
print(my_generator)
for i in my_generator: # generator也可以for呼叫
print(i)
結果
object
at 0x02c1ec00>01
2
像上面那樣就構造生成器了,可以用for遍歷,注:
list = [i for i in range(3)]
這樣就是列表了
list1 = [1, 2, 3, 4]
list1_iter = iter(list1) # 獲取迭代器
print(list1_iter)
for x in list1_iter: # 也可以迭代資料
print(x)
結果:
object
at 0x008d8950>12
34
迭代器也可以被for迭代
迭代器:乙個物件,如果實現了__iter__和__next__,以為就是迭代器,像:
from collections import iterable
class
myiter
(object):
def__init__
(self, *args):
self.mylist = args
self.current = 0
def__iter__
(self):
return self
def__next__
(self):
if self.current < len(self.mylist):
item = self.mylist[self.current]
self.current += 1
return item
else:
raise stopiteration
if __name__ == '__main__':
myiter = myiter(1, 2, 3, 4)
print(isinstance(myiter, iterable))
for i in myiter:
print(i)
結果:
true12
34
生成器:只要def中有yield關鍵字,就是乙個生成器,(在這裡把def說成函式不太舒服)。另外,還有例子一的產生生成器的方式。
yield生成器如:
def
my_generator
():for index in [1, 2, 3]:
yield index
t = my_generator()
print(t)
for i in t:
print(i)
結果
object
my_generator
at 0x0364ec00>12
3
他們都可以被for遍歷,因為for首先判斷物件是否可以遍歷,之後一直呼叫next(),直到捕獲stopiteration的異常結束,而迭代器有__next__方法,而yield可以被next啟用,如
import time
i = [1, 2, 3, 4]
i_iter = iter(i) # 獲取迭代器
print(next(i_iter))
print(next(i_iter))
print(next(i_iter))
print(next(i_iter))
time.sleep(1)
print(next(i_iter))
# 超出範圍會丟擲異常 stopiteration
結果
123
4traceback (most recent call
last):
file "c:/users/51613/desktop/myprogram/協程,迭代器生成器/用法iter()next().py", line 10, in
print(next(i_iter))
stopiteration
迭代器被next呼叫,超出範圍拋stopiteration異常
import time
defgen
(): i = 0
while i < 4:
yield i
i += 1
g = gen()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
time.sleep(0.5) # 讓輸出好看點
print(next(g))
結果:
012
3traceback (most recent call
last):
file "c:/users/51613/desktop/myprogram/協程,迭代器生成器/next啟用yield.py", line 16, in
print(next(g))
stopiteration
yield的作用:儲存當前執行狀態,然後暫停,即將生成器(函式)掛起;將yield關鍵字後面表示式的值作為返回值返回。
生成器可以被next呼叫,yield被next啟用,超出範圍拋異常。
除了next可以啟用yield以外,send也可以:
import time
defsend_yield
(): i = 0
while i < 5:
temp = yield i
print(temp)
i += 1
g = send_yield()
print(g.send(none)) # send之前需要啟用。用none啟用,或者next()啟用。
print(g.send("luo"))
print(g.send("luo"))
print(g.send("luo"))
print(g.send("luo"))
time.sleep(1)
print(g.send("luo"))
結果:
0
luo1
luo2
luo3
luo4
luotraceback (most recent call
last):
file "c:/users/51613/desktop/myfirstprogram/協程,迭代器生成器/send()喚醒生成器yield.py", line 19, in
print(g.send("luo"))
stopiteration
send可以啟用yield,超出也會丟擲異常,不同的是,他可以傳參,並且這個引數可以在程式內接收。
生成器 迭代器
最近見天一直在看廖大的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...