生成器
Python技術分享—生成器
有時候,序列或集合內的元素的個數非常巨大,如果全制造出來并放入內存,對計算機的壓力是非常大的。比如,假設需要獲取一個10**20次方如此巨大的數據序列,把每一個數都生成出來,并放在一個內存的列表內,這是粗暴的方式,有如此大的內存么?如果元素可以按照某種算法推算出來,需要就計算到哪個,就可以在循環(huán)的過程中不斷推算出后續(xù)的元素,而不必創(chuàng)建完整的元素集合,從而節(jié)省大量的空間。在Python中,這種一邊循環(huán)一邊計算出元素的機制,稱為生成器:generator。
生成生成器:
g = (x * x for x in range(1, 4))
g
<generator object <genexpr> at 0x1022ef630>
可以通過next()函數獲得generator的下一個返回值,這點和迭代器非常相似:
next(g)
1
next(g)
4
next(g)
9
next(g)
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
next(g)
StopIteration
------------------------------------------------
但更多情況下,我們使用for循環(huán)。
for i in g:
print(i)
除了使用生成器推導式,我們還可以使用yield關鍵字。
def createNums():
print("----func start------")
a,b = 0,1
for i in range(5):
# print(b)
print("--1--")
yield b
print("--2--")
a,b = b,a+b # a,b = 1, 1 a,b = 1,2
print("--3--")
print("----func end------")
g= createNums()
next(g) # 如果想得到y(tǒng)ield的值,可以打印next(g)
在 Python中,使用yield返回的函數會變成一個生成器(generator)。 在調用生成器的過程中,每次遇到y(tǒng)ield時函數會暫停并保存當前所有的運行信息,返回yield的值。并在下一次執(zhí)行next()方法時從當前位置繼續(xù)運行。
# 斐波那契函數
def fibonacci(n):
a = 0
b = 1
counter = 0
while True:
if counter > n:
return
yield a # yield讓該函數變成一個生成器
a, b = b, a + b
counter += 1
fib = fibonacci(10) # fib是一個生成器
print(type(fib))
for i in fib:
print(i, end=" ")
生成器是可以循環(huán)的,相比next來說,for循環(huán)更友好
a = createNums()
這兩種取值方式是一樣的!??!
a.__next__()
next(a)
for i in a:
print(i)
send
def test():
i = 0
while i<5:
temp = yield i
print(temp)
i+=1
t = test()
next(t)
next(t)
t.send("juran")
next(t)
--------------------------------------------
t = test()
t.send("juran")
Traceback (most recent call last):
File "/Users/binbin/Desktop/Python/demo.py", line 179, in <module>
t.send("juran")
TypeError: can't send non-None value to a just-started generator
如何解決這個錯誤?
> next(t)
t.send("juran")
> send(None)
生成器的應用
實現多任務
def test1():
while True:
print("--1--")
yield None
def test2():
while True:
print("--2--")
yield None
t1 = test1()
t2 = test2()
while True:
next(t1)
next(t2)
(寫在最后,由于以后每天晚上九點半之后會更新Python基礎的知識點,記得來看哦?。?/strong>
此文來源于微博和今日頭條:邏二妞,轉載請注明出處,謝謝