成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

10分鐘了解Python黑魔法 Yield、Iterator、Generator

開發(fā)
今天,我們來討論Python的yield、Iterator和generator,它們可以在許多教程中看到,但總是引起一些混淆。

今天,我們來討論Python的yield、Iterator和generator,它們可以在許多教程中看到,但總是引起一些混淆。

今天,我們來討論Python的yield、Iterator和generator,它們可以在許多教程中看到,但總是引起一些混淆。

就像decorators一樣,這三個概念是緊密聯(lián)系在一起的。例如,如果你想知道什么是yield,你必須首先了解什么是generator。但在理解generator之前,你又必須理解iterator是什么,但在理解iterator之前,您必須要知道iterable對象是什么。他們的關(guān)系如下圖:

Iterables 可迭代的

可迭代是指能夠通過迭代的方法遍歷的對象,比如列表、字符串、元組、字典、集合等等。簡單的例子:

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

可迭代對象如何工作?

讓我們看看Python解釋器在遇到迭代操作時如何處理迭代,例如for ... in x

  • 調(diào)用 iter(x) 函數(shù)
  • 檢查對象是否實現(xiàn)了 _iter__ 方法,如果實現(xiàn)了,則調(diào)用它以獲取迭代器;
  • 如果未實現(xiàn) _iter__ 方法,但實現(xiàn)了_getitem__ 方法,Python將創(chuàng)建一個迭代器并嘗試按順序獲取元素(從索引0開始);
  • 如果兩個方法都未實現(xiàn),將拋出TypeError異常,指示無法迭代該對象。

因此具有 __iter__ 方法或 __getitem__方法的對象通常稱為可迭代對象。

如何判斷一個對象是否可迭代?

  • 方法一:使用dir函數(shù),檢查對象是否實現(xiàn)了__iter__ 或者 __getitem__方法。
mylist = [1, 2, 3]
mylistMethod = dir(mylist)
print(mylistMethod) #查看mylist的方法
print('__iter__' in dir(mylist) or '__getitem__' in dir(mylist)) # True
  • 方法二:使用isinstance函數(shù),檢查對象是否是Iterable類型。
from collections import Iterable
mylist = [1, 2, 3]
print(isinstance(mylist, Iterable)) # True

Iterator 迭代器

迭代器是一個包含可數(shù)數(shù)量值的對象。它可以迭代,這意味著您可以遍歷所有值。讓我們看一個迭代器示例:

for i in range(5):
    print(i) # 0 1 2 3 4

像這樣,一個個打印元素的過程就叫可迭代的,這個過程也是我們?nèi)粘4a編寫中接觸最多的操作。

簡單來說,帶有next()方法的可迭代對象就是一個迭代器,或者說一個可迭代對象和一個迭代器的關(guān)系是:Python從一個可迭代對象中獲取一個迭代器。具體關(guān)系如下圖:

所以上面提到的列表、字符串等不是迭代器。但是,您可以使用Python內(nèi)置 iter()函數(shù)來獲取它們的迭代器對象。讓我們使用迭代器模式來重寫前面的例子:

mylist = [1,2,3]
it = iter(mylist) # 獲取迭代器對象
while True:
    try:
        print(next(it))
    except StopIteration:
        print("Stop iteration!")
        break

在上面的代碼中,我們首先使用iterable對象mylist來構(gòu)造迭代器it,并不斷調(diào)用迭代器上的next()函數(shù)來獲取下一個元素。如果沒有字符,迭代器將拋出 StopIteration 異常并退出循環(huán)。

Generator 生成器

Python 提供了一個生成器來創(chuàng)建迭代器函數(shù)。生成器是一種特殊類型的函數(shù),它不返回單個值,而是返回一個包含一系列值的迭代器對象。在生成器函數(shù)中,使用 yield 語句而不是 return 語句。

現(xiàn)在我們已經(jīng)知道for循環(huán)背后的機制了,但是如果數(shù)據(jù)量太大,比如for i in range(1000000),使用for循環(huán)將所有的值存儲在內(nèi)存中不僅占用大量的存儲空間 但是如果我們只需要訪問前幾個元素,空間就浪費了。在這種情況下,我們可以使用 generator 。

生成器的思路是,我們不需要一次性把這個列表全部創(chuàng)建出來,只需要記住它的創(chuàng)建規(guī)則,然后在需要用到的時候,再一次次的計算和創(chuàng)建。我們來看一個例子:

my_generator = (x*x for x in range(10))
for i in my_generator:
    print(i) # 0 1 4 9 16 25 36 49 64 81

my_generator 是一個生成器,它的每一個元素都是一個生成器對象。我們可以使用 next()函數(shù)來獲取下一個元素。

Yield 產(chǎn)生器

簡單來說,你可以把yield當(dāng)成return,但它返回的是一個生成器。記住,剛開始學(xué)習(xí)的時候不需要了解這個yield是什么,但是一定要了解它的運行機制!讓我們看一下下面的代碼片段:

def test():
    print("First")
    yield 1
    print("Second")
    yield 2
    print("Third")
    yield 3
my_generator = test() # 創(chuàng)建生成器
print(type(my_generator)) # <class 'generator'>

我們可以在這里看到如果一個函數(shù)使用 yield 作為返回值,那么它就變成了一個生成器函數(shù)。與普通函數(shù)不同,生成器函數(shù)被調(diào)用后,函數(shù)體中的代碼不會立即執(zhí)行(執(zhí)行my_generator=test()后不打印任何值),而是返回一個生成器!正如我們前面提到的:generator 是迭代器,而 yield 可以被視為 return ,不難猜測下面代碼的結(jié)果:

def test():
    print("First")
    yield 1
    print("Second")
    yield 2
    print("Third")
    yield 3
for item in test():
    print(item)
# 輸出:
"""
First
1
Second
2
Third
3
"""

next 函數(shù)是如何運行的?

def test():
    print("First")
    yield 1
    print("Second")
    yield 2
    print("Third")
    yield 3

my_generator = test() # 創(chuàng)建生成器
a = next(my_generator) # First
print(a) # 1
b = next(my_generator) # Second
print(b) # 
c = next(my_generator) # Third
print(c) # 3
d = next(my_generator) # StopIteration
print(d) # error

每次調(diào)用next(my_generator),只跑到y(tǒng)ield位置就停止,下次再跑,從上次結(jié)束的位置開始!并且生成器的長度取決于在函數(shù)中定義 yield 的次數(shù)。看起來也很好理解呢。

如果理解了上面的 yield 函數(shù)示例,讓我們繼續(xù)看一個更復(fù)雜的示例,該生成器可以接受參數(shù)。

def simple_gen(a):
    print('-> Started: a =', a)
    b = yield a
    print('-> Received: b =', b)
    c = yield a + b
    print('-> Received: c =', c)
gen = simple_gen(14)
next(gen) # -> Started: a = 14
next(gen) # ?
next(gen) # ?

運行結(jié)果如圖:

發(fā)生了什么??從第一次 next(gen) 調(diào)用開始,它在 yield a 處停止,然后當(dāng)您再次調(diào)用 next(gen) 時,b 實際上是 None 值,這導(dǎo)致了異常。

b 為什么是 None 值?因為我們在 yield a 處沒有接收到任何值,所以 b 就是 None 值。要想接收值,

要繼續(xù),您需要使用 send() 函數(shù):生成器發(fā)送(值)恢復(fù)執(zhí)行并將值“發(fā)送”到生成器函數(shù)中。value 參數(shù)成為當(dāng)前 yield 表達式的結(jié)果。send() 方法返回生成器生成的下一個值,或者如果生成器退出而沒有生成另一個值則引發(fā) StopIteration。

怎么理解send() 函數(shù)?一個帶參數(shù)的 next(),接收參數(shù),執(zhí)行yield,然后返回值。

def simple_gen(a):
    print('-> Started: a =', a)
    b = yield a
    print('-> Received: b =', b)
    c = yield a + b
    print('-> Received: c =', c)
gen = simple_gen(14)
next(gen) # -> Started: a = 14
gen.send(15) # Received: b = 15 # send 15 to generator,并執(zhí)行下一步 send包含next的yield

總結(jié)

小思考:

  • yield 和 return 的區(qū)別,你理解了么?
  • yield, generator  和 iterator 的區(qū)別和聯(lián)系,你理解了么?
責(zé)任編輯:華軒 來源: 哈希編程
相關(guān)推薦

2020-10-13 18:22:58

DevOps工具開發(fā)

2021-05-17 20:13:50

數(shù)倉操作型數(shù)據(jù)庫

2017-07-28 10:05:58

Pythonyieldgenerator

2018-05-06 16:26:03

關(guān)聯(lián)規(guī)則數(shù)據(jù)分析關(guān)聯(lián)規(guī)則推薦

2018-03-12 21:31:24

區(qū)塊鏈

2009-11-05 14:53:54

Visual Stud

2021-10-19 07:27:08

HTTP代理網(wǎng)絡(luò)

2021-04-30 16:23:58

WebRTC實時音頻

2023-09-07 23:52:50

Flink代碼

2022-12-16 09:55:50

網(wǎng)絡(luò)架構(gòu)OSI

2018-11-28 11:20:53

Python函數(shù)式編程編程語言

2021-07-15 06:43:11

Bash調(diào)試腳本

2013-09-13 14:08:01

2017-07-06 08:12:02

索引查詢SQL

2018-03-12 14:37:50

區(qū)塊鏈比特幣架構(gòu)

2024-06-25 12:25:12

LangChain路由鏈

2022-07-18 06:16:07

單點登錄系統(tǒng)

2018-03-23 11:56:09

相似性推薦推薦算法推薦

2009-11-09 12:55:43

WCF事務(wù)

2019-07-18 16:32:06

Python函數(shù)數(shù)據(jù)
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 一区二区精品视频 | 九九热精品免费 | 成人免费毛片在线观看 | 久久久久亚洲精品中文字幕 | 狠狠躁天天躁夜夜躁婷婷老牛影视 | 欧美精品一区二区在线观看 | 日韩欧美三级在线 | 国产欧美一区二区三区在线看蜜臀 | 天天操夜夜操 | 日韩成人精品在线 | 久久久成人精品 | 在线免费观看黄色 | 国产精品视频网 | 91视频精选 | 亚洲视频免费在线观看 | 青青草国产在线观看 | 午夜视频免费在线观看 | 国产一级免费视频 | 91久久久久久 | 中文一区二区 | 精久久久久 | 麻豆久久久9性大片 | 久久蜜桃精品 | 久久免费小视频 | 精品一区二区三区91 | 鸳鸯谱在线观看高清 | 欧美精品成人 | 欧美福利视频 | 超碰成人免费 | 国产精品久久久久久久久久久免费看 | 手机av网 | 久久99久久| 亚洲成人www | 91精品久久久久久久久久入口 | av男人的天堂在线 | 日韩欧美国产精品一区二区 | 精品国产一区二区三区在线观看 | 日韩欧美网 | av喷水 | 欧美日韩国产一区二区 | 欧美中国少妇xxx性高请视频 |