免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
【Python之路】特別篇
生成器(constructor)

  生成器函數(shù)在Python中與迭代器協(xié)議的概念聯(lián)系在一起。包含yield語句的函數(shù)會被特地編譯成生成器 !!!

  當函數(shù)被調(diào)用時,他們返回一個生成器對象,這個對象支持迭代器接口。

  不像一般的函數(shù)會生成值后退出,生成器函數(shù)在生成值后會自動掛起并暫停他們的執(zhí)行和狀態(tài),他的本地變量將保存狀態(tài)信息,這些信息在函數(shù)恢復(fù)時將再度有效

創(chuàng)建生成器方式有兩種:

方法一:

1
s = ( x for x in range(5) )

方法二:

1
2
3
def foo():
    print('OK')
    yield 1

例子:

1
2
3
4
5
6
def g(n):
    for i in range(n):
        yield i **2
for i in g(5):
    print(i)

要了解他的運行原理,我們來用next方法看看:

1
2
3
4
5
6
7
8
9
10
11
t = g(5)
print(t.__next__())      # 0
print(t.__next__())      # 1
print(t.__next__())      # 4
print(t.__next__())      # 9
print(t.__next__())      # 16
print(t.__next__())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

在運行完5次next之后,生成器拋出了一個StopIteration異常,迭代終止。

send(msg) 與 next()

了解了next()如何讓包含yield的函數(shù)執(zhí)行后,我們再來看另外一個非常重要的函數(shù)send(msg)。

其實next()和send()在一定意義上作用是相似的,區(qū)別是send()可以傳遞yield表達式的值進去,而next()不能傳遞特定的值,只能傳遞None進去。因此,我們可以看做

c.next() 和 c.send(None) 作用是一樣的。

1
2
3
4
5
6
7
8
9
10
11
def g(n):
    for i in range(n):
        ret = yield i **2
        print(ret)
t = g(5)
print(t.__next__())
print(t.send('Hello'))
# 0 Hello 1

需要注意的是,第一次調(diào)用時,請使用next()語句或是send(None),不能使用send發(fā)送一個非None的值,否則會出錯的,因為沒有yield語句來接收這個值。

send(msg) 和 next()是有返回值的,它們的返回值很特殊,返回的是yield表達式的參數(shù) !

執(zhí)行順序是:遇到y(tǒng)ield 先返回值,等下次再進入時再用 msg 進行賦值?。。?/p>

再來看一個yield的例子,用生成器生成一個Fibonacci數(shù)列:

1
2
3
4
5
6
7
8
9
10
def fab(max):
    a, b = 0, 1
    while a < max:
        yield a
        a, b = b, a + b
for i in fab(20):
    print(i)
# 0 1 1 2 3 5 8 13

另一個 yield 的例子來源于文件讀取。

1
2
3
4
5
6
7
8
9
def read_file(fpath):
   BLOCK_SIZE = 1024
   with open(fpath, 'rb') as f:
       while True:
           block = f.read(BLOCK_SIZE)
           if block:
               yield block
           else:
               return

  

迭代器(iterator)

  for循環(huán)可以用于Python中的任何類型,包括列表、元祖等等,實際上,for循環(huán)可用于任何“可迭代對象”!

  迭代器是一個實現(xiàn)了迭代器協(xié)議的對象,Python中的迭代器協(xié)議就是有next方法的對象會前進到下一結(jié)果,而在一系列結(jié)果的末尾是,則會引發(fā)StopIteration。

  任何這類的對象在Python中都可以用for循環(huán)或其他遍歷工具迭代,迭代工具內(nèi)部會在每次迭代時調(diào)用next方法,并且捕捉StopIteration異常來確定何時離開。

  使用迭代器一個顯而易見的好處就是:每次只從對象中讀取一條數(shù)據(jù),不會造成內(nèi)存的過大開銷。

注意

  判斷迭代器的條件是:

  1. 有__iter__ 方法

  2. 有__next__ 方法

  所有的生成器都是迭代器!

迭代器例子:

比如要逐行讀取一個文件的內(nèi)容,利用readlines()方法,我們可以這么寫:

1
2
for line in open("test.txt").readlines():
    print (line)

這樣雖然可以工作,但不是最好的方法。因為他實際上是把文件一次加載到內(nèi)存中,然后逐行打印。當文件很大時,這個方法的內(nèi)存開銷就很大了。

利用file的迭代器,我們可以這樣寫:

1
2
for line in open("test.txt"):
    print (line)

這是最簡單也是運行速度最快的寫法,他并沒顯式的讀取文件,而是利用迭代器每次讀取下一行。

for 循環(huán)實質(zhì)

  1. 調(diào)用 __iter__ 方法將可迭代對象轉(zhuǎn)換成迭代器

  2. 對迭代器對象不斷調(diào)用 __next__ 方法

  3. 處理StopIteration 異常

View Code

 

可迭代對象(iterable)

  判斷條件:內(nèi)部具有 __iter__ 方法

1
2
3
4
5
6
from collections import Iterable,Iterator
print(isinstance(range(1),Iterable))
print(isinstance(range(1),Iterator))
print(isinstance(list(),Iterable))
print(isinstance(list(),Iterator))

  

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Python生成器和迭代器有什么用?
Python迭代和生成操作小結(jié)
Python第六章-函數(shù)05-迭代器&生成器
Iterator迭代器和生成器
Python迭代器定義及用法詳解
python 生成器 & 迭代器
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服