【Python基础】弄懂这几个问题,拿下 Python 生成器!
我的施工之路
1我的施工計劃
2數字專題
3字符串專題
4列表專題
5流程控制專題
6編程風格專題
7函數使用
8面向對象編程(上篇)
9面向對象編程(下篇)
10十大數據結構
11包和模塊使用總結
12Python正則專題總結
13設計模式
14Python時間模塊總結
15?Python 裝飾器
16?Python 迭代器
今天介紹生成器和yield的用法,通過如下8、9個小問題,相信大家會對它們有一點新的認識。
1 什么是可迭代對象?
可迭代對象,英文Iterable,是一個形容詞,這類對象和Java語言類似,都可看作是一類接口,抽象地描述事物具備怎樣的能力。所以,Iterable自然具備可迭代能力。
如下,常見的list,Iterator等都是Iterable對象:
In?[33]:?from?collections.abc?import?Iterable,Iterator??????????????????????In?[34]:?issubclass(list,Iterable)?????????????????????????????????????????? Out[34]:?TrueIn?[35]:?issubclass(Iterator,Iterable)?2 什么是一個生成器?
生成器是可迭代的(Iterable),最簡單的創建生成器方法是通過一對(),如下所示:
In?[37]:?g?=?(i*i?for?i?in?[1,4,0])?????????????????????????????????????????In?[38]:?g?????????????????????????????????????????????????????????????????? Out[38]:?<generator?object?<genexpr>?at?0x7fe8956e96d0>g 是一個生成器對象,generator object
獲取生成器對象的元素,可使用next函數,如下所示,獲取第一個元素:
In?[39]:?next(g)???????????????????????????????????????????????????????????? Out[39]:?1獲取第二個元素:
In?[40]:?next(g)???????????????????????????????????????????????????????????? Out[40]:?163 創建生成器的幾種方法?
如上所見,使用一對()能夠創建一個生成器對象。
除此之外,想必大家也都知道,是使用關鍵字 yield. yield出現在一個函數中,運行到yield處,返回的對象便是生成器對象(generator object).
4 生成器是迭代器嗎?
生成器對象(generator object)一定也是迭代器對象(Iterator object),如上面的生成器g,使用內置函數isinstance驗證,返回True:
In?[43]:?isinstance(g,Iterator)????????????????????????????????????????????? Out[43]:?True因此,它具備一切迭代器的特性,關于迭代器我們已在上一個話題討論,簡而言之,迭代器的幾個特點:
是有去無回的,
迭代器無需提前知道整個列表的所有元素,
無需加載所有元素到RAM中盡而它是節省內存的(memory-efficient).
生成器同樣具備這些特性。除此之外,它還有一些獨有的特性,下面跟隨yield 我們便能看出來。
5 如何用一句話描述 yield?
yield 關鍵字的用法在stackoverflow上也是最熱的問題之一,借用一個最熱回答中的解釋:
yield is a keyword that is used like return, except the function will return a generator.
”yield 是一個特殊的return, 它返回一個生成器對象。
說實話,理解這些只是皮毛。那么,如何精通yield的用法呢?
6 如何精通yield的用法?
要想精通yield,你必須首先搞清楚一點:
當你調用帶有yield的函數時,函數并沒有執行任何一行,只是返回一個生成器對象
為了幫助大家理解,創建一個帶有yield的函數:
def?gfun():mylist?=?range(3)for?i?in?mylist:yield?i*ig?=?gfun() print(g)為了加深印象,你可以自己調試驗證一遍,函數第一行打的斷點始終未被命中。
帶yield的函數和for結合使用,第一次調用上一步創建的生成器對象后,將會進入函數體直到遇到yield返回值。
然后,for循環再進入函數時,直接跑到yield的下一句。直到生成器對象變空為止。
使用下面代碼演示yield的上面過程:
def?createGenerator():mylist?=?range(3)for?i?in?mylist:yield?i*iprint(i*i)g?=?createGenerator() print(g) for?gi??in?g:pass參考錄制的gif:
7 yield 都有哪些重要價值?
Python引入yield后,便擁有具備實現協程的能力,協程的確是一種高效的編程模型,關于協程的理解,后面專題會詳細討論。包括更高級的功能如異步等,根基都是yield.
8 yield 和 itertools
yield重要性和使用廣泛性還提現在,Python單獨一個模塊專門用于管理迭代器和生成器對象,便是itertools,里面封裝的方法特性后面再討論。
9 yield 使用案例
yield實現浮點數步長的frange:
def?frange(start,end,step):i?=?startwhile?i<end:yield?round(i,3)i+=step調用frange:
for?item?in?frange(10,14,0.8):print(item)結果:
10 10.8 11.6 12.4 13.2最后總結今天討論的幾個問題:
1 什么是可迭代對象?
2 什么是一個生成器?
3 創建生成器的幾種方法?
4 生成器是迭代器嗎?
5 如何用一句話描述 yield?
6 如何精通yield的用法?
7 yield 都有哪些重要價值?
8 yield 和 itertools
9 yield 使用案例
總結
以上是生活随笔為你收集整理的【Python基础】弄懂这几个问题,拿下 Python 生成器!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科研狗的国庆与普通人的国庆有什么不同?
- 下一篇: 【小白学PyTorch】17.TFrec