欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python 代碼中的 yield 關(guān)鍵字到底是什么

 更新時間:2024年07月29日 09:12:04   作者:WanWuJieKeLian  
yield是Python中一個強大的工具,它可以幫助你以一種高效的方式處理大量數(shù)據(jù),理解yield的工作原理對于掌握Python編程至關(guān)重要,這篇文章主要介紹了Python 代碼中的 yield 到底是什么,需要的朋友可以參考下

在Python編程中,有一個強大而神秘的關(guān)鍵字,那就是yield。初學(xué)者常常被它搞得暈頭轉(zhuǎn)向,而高級開發(fā)者則借助它實現(xiàn)高效的代碼。到底yield是什么?它又是如何在Python代碼中發(fā)揮作用的呢?讓我們一起來揭開它的面紗。

Python里的一個非常重要但也頗具迷惑性的關(guān)鍵詞——yield。

什么是yield?為什么我們需要在Python中使用它?

來,讓我們一起來拆解一下,看看yield到底是個啥。

迭代與可迭代對象

要搞明白yield,咱們先得弄清楚什么是可迭代對象(iterables)。

所謂可迭代對象,簡單來說,就是你可以逐個讀取其元素的對象,比如列表、字符串、文件等等。舉個例子,當你創(chuàng)建一個列表時,你可以用for循環(huán)一個個地讀取它的元素:

mylist = [1, 2, 3]
for i in mylist:
print(i)

輸出會是:

1
2
3

這里的mylist就是一個可迭代對象。你還可以用列表推導(dǎo)式(list comprehension)來創(chuàng)建一個列表,它同樣也是可迭代的:

mylist = [x*x for x in range(3)]
for i in mylist:
print(i)

輸出是:

1
2
3

凡是你可以用for... in...來操作的東西,都是可迭代對象,包括列表、字符串、文件等等。

可迭代對象非常方便,因為你可以任意多次地讀取它們的值,但前提是你得把所有值都存儲在內(nèi)存里。這就帶來了一個問題:當數(shù)據(jù)量很大時,這種方式顯然不太合適。

生成器

生成器(generators)是迭代器的一種,你只能遍歷它們一次。生成器不像列表那樣把所有的值都存儲在內(nèi)存里,而是即用即生成。來看看生成器的例子:???????

mygenerator = (x*x for x in range(3))
for i in mygenerator:
print(i)

輸出和列表推導(dǎo)式一樣:???????

0
1
4

但注意了,生成器只能使用一次,因為它們會“邊用邊忘”:計算0后忘記0,計算1后忘記1,最后計算4后結(jié)束。再用同一個生成器對象做for循環(huán)就沒有結(jié)果了。

yield關(guān)鍵詞

說到y(tǒng)ield,這是個類似于return的關(guān)鍵詞,但它返回的不是一個值,而是一個生成器??纯催@個例子:???????

def create_generator():
mylist = range(3)
for i in mylist:
yield i*i
mygenerator = create_generator() # 創(chuàng)建一個生成器
print(mygenerator) # mygenerator 是一個生成器對象!

輸出是:

<generator object create_generator at 0xb7555c34>

通過for循環(huán)遍歷這個生成器:???????

for i in mygenerator:
print(i)

輸出:???????

0
1
4

這個例子看起來簡單,但它在處理大量數(shù)據(jù)時特別有用,因為生成器只在需要時生成值,而不是一次性生成所有值然后存儲在內(nèi)存中。

深入理解yield

為了徹底掌握yield,我們需要理解當調(diào)用生成器函數(shù)時,函數(shù)體內(nèi)的代碼并不會立即執(zhí)行。函數(shù)返回的是一個生成器對象,然后你的代碼會在每次調(diào)用for循環(huán)時從上次中斷的地方繼續(xù)執(zhí)行,直到遇到下一個yield。

第一次調(diào)用for循環(huán)時,生成器對象會從頭開始運行函數(shù)中的代碼,直到遇到y(tǒng)ield,然后返回循環(huán)中的第一個值。隨后的每次調(diào)用都會執(zhí)行函數(shù)中循環(huán)的下一次迭代,直到生成器不再有值返回。這可能是因為循環(huán)結(jié)束了,或者條件不再滿足。

來看看一個實際的例子:?

 def _get_child_candidates(self, distance, min_dist, max_dist):
     if self._leftchild and distance - max_dist < self._median:
         yield self._leftchild
     if self._rightchild and distance + max_dist >= self._median:
         yield self._rightchild

這里的代碼在每次使用生成器對象時都會被調(diào)用:

如果節(jié)點對象還有左子節(jié)點并且距離合適,返回下一個子節(jié)點。

如果節(jié)點對象還有右子節(jié)點并且距離合適,返回下一個子節(jié)點。

如果沒有更多子節(jié)點,生成器會被認為是空的。

調(diào)用這個生成器的方法如下:???????

 result, candidates = list(), [self]
 while candidates:
     node = candidates.pop()
     distance = node._get_dist(obj)
     if distance <= max_dist and distance >= min_dist:
         result.extend(node._values)
     candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))
 return result

這里的代碼有幾個巧妙之處:

  • 循環(huán)遍歷一個列表,而列表在循環(huán)過程中會擴展。這樣可以方便地遍歷所有嵌套的數(shù)據(jù),雖然有些危險,因為可能會陷入無限循環(huán)。在這個例子中,candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))用盡生成器的所有值,但while循環(huán)不斷創(chuàng)建新的生成器對象,因為它們作用在不同的節(jié)點上會產(chǎn)生不同的值。
  • extend()方法是列表對象的方法,它期望一個可迭代對象,并將其值添加到列表中。通常我們傳遞一個列表給它,但在代碼中,它接收一個生成器,這是個好主意,因為:
  • 你不需要讀取值兩次。
  • 你可能有很多子節(jié)點,不想全部存儲在內(nèi)存中。

這段代碼展示了Python為何如此酷:它不在乎方法的參數(shù)是列表還是其他可迭代對象。這種特性叫鴨子類型(duck typing),也是Python靈活性的一個體現(xiàn)。

高級用法

再來看一個更高級的用法——控制生成器的耗盡:???????

 class Bank():
     crisis = False
      def create_atm(self):
         while not self.crisis:
              yield "$100"
  hsbc = Bank()
  corner_street_atm = hsbc.create_atm()
  print(next(corner_street_atm)) # 輸出 $100
 print(next(corner_street_atm)) # 輸出 $100
 print([next(corner_street_atm) for _ in range(5)]) # 輸出 ['$100', '$100', '$100', '$100', '$100']
 hsbc.crisis = True
 print(next(corner_street_atm)) # 輸出 StopIteration

這里我們模擬了一個ATM機,在銀行沒有危機時,你可以不斷取錢,但一旦危機來了,ATM機就會停止工作,即使是新的ATM機也不能再取錢了。

itertools模塊

最后,給大家介紹一個非常有用的模塊——itertools。這個模塊包含了很多操作可迭代對象的特殊函數(shù)。如果你曾經(jīng)希望復(fù)制一個生成器、連接兩個生成器、用一行代碼將值分組到嵌套列表中,或者在不創(chuàng)建另一個列表的情況下使用map和zip,那么就應(yīng)該導(dǎo)入itertools。

舉個例子,我們看看四匹馬比賽的可能到達順序:???????

import itertools
horses = [1, 2, 3, 4]
races = itertools.permutations(horses)
print(list(itertools.permutations(horses)))

輸出:

[(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 1, 3, 4), (2, 1, 4, 3), (2, 3, 1, 4), (2, 3, 4, 1), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]

itertools模塊簡直是Python程序員的好伙伴,可以讓你在處理迭代對象時如虎添翼。

總結(jié)

yield是Python中一個強大的工具,它可以幫助你以一種高效的方式處理大量數(shù)據(jù)。理解yield的工作原理對于掌握Python編程至關(guān)重要。

在大數(shù)據(jù)時代,處理海量數(shù)據(jù)已成為常態(tài)。生成器作為一種高效的數(shù)據(jù)處理方式,因其優(yōu)越的內(nèi)存管理能力,受到了越來越多開發(fā)者的青睞。無論是日志處理、數(shù)據(jù)流分析,還是實時數(shù)據(jù)處理,生成器都展現(xiàn)了不可替代的價值。

通過對yield的詳解,我們不僅理解了它的基本概念和用法,還認識到它在高效數(shù)據(jù)處理中的重要性。掌握yield,將為你的Python編程之旅增添一把利器。

到此這篇關(guān)于Python 代碼中的 yield 關(guān)鍵字到底是什么的文章就介紹到這了,更多相關(guān)Python 代碼中的 yield 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • PyQt4 treewidget 選擇改變顏色,并設(shè)置可編輯的方法

    PyQt4 treewidget 選擇改變顏色,并設(shè)置可編輯的方法

    今天小編就為大家分享一篇PyQt4 treewidget 選擇改變顏色,并設(shè)置可編輯的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • Python爬蟲之爬取最新更新的小說網(wǎng)站

    Python爬蟲之爬取最新更新的小說網(wǎng)站

    這篇文章主要介紹了Python爬蟲之爬取最新更新的小說網(wǎng)站,文中有非常詳細的代碼示例,對正在學(xué)習(xí)python爬蟲的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • Python線程池的實現(xiàn)淺析

    Python線程池的實現(xiàn)淺析

    當有多個?IO?密集型的任務(wù)要被處理時,我們自然而然會想到多線程。而線程池的實現(xiàn)也很簡單,因為?Python?提供了一個標準庫?concurrent.futures,已經(jīng)內(nèi)置了對線程池的支持。所以本篇文章,我們就來詳細介紹一下該模塊的用法
    2022-08-08
  • python matplotlib庫繪制散點圖例題解析

    python matplotlib庫繪制散點圖例題解析

    這篇文章主要介紹了python matplotlib庫繪制散點圖例題解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • python3.5基于TCP實現(xiàn)文件傳輸

    python3.5基于TCP實現(xiàn)文件傳輸

    這篇文章主要為大家詳細介紹了python3.5基于TCP實現(xiàn)文件傳輸?shù)拇a,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • tensorflow ckpt模型和pb模型獲取節(jié)點名稱,及ckpt轉(zhuǎn)pb模型實例

    tensorflow ckpt模型和pb模型獲取節(jié)點名稱,及ckpt轉(zhuǎn)pb模型實例

    今天小編就為大家分享一篇tensorflow ckpt模型和pb模型獲取節(jié)點名稱,及ckpt轉(zhuǎn)pb模型實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • python使用opencv resize圖像不進行插值的操作

    python使用opencv resize圖像不進行插值的操作

    這篇文章主要介紹了python使用opencv resize圖像不進行插值的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 詳解python中的hashlib模塊的使用

    詳解python中的hashlib模塊的使用

    這篇文章主要介紹了python中的hashlib模塊的使用,非常不錯,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-04-04
  • Python類方法@classmethod()的具體使用

    Python類方法@classmethod()的具體使用

    @classmethod 是一個函數(shù)修飾符,它表示接下來的是一個類方法,而對于平常我們見到的則叫做實例方法,本文主要介紹了Python類方法@classmethod()的具體使用,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 推薦系統(tǒng)MostPopular算法的Python實現(xiàn)方式

    推薦系統(tǒng)MostPopular算法的Python實現(xiàn)方式

    這篇文章主要介紹了推薦系統(tǒng)MostPopular算法的Python實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評論