1. 程式人生 > 資訊 >華為全屋智慧全國最大授權體驗店落地北京,讓你離未來的家更近一步(附全國各大門店列表)

華為全屋智慧全國最大授權體驗店落地北京,讓你離未來的家更近一步(附全國各大門店列表)

生成器

生成器本質上也是迭代器,但更為特殊以 list 容器為例,在使用該容器迭代一組資料時,
必須事先將所有資料儲存到容器中,才能開始迭代;而生成器卻不同,它可以實現在迭代的同時生成元素。

不僅如此,生成器的建立方式也比迭代器簡單很多,大體分為以下 2 步:
定義一個以 yield 關鍵字標識返回值的函式;
呼叫剛剛建立的函式,即可建立一個生成器。


def intNum():
    print("開始執行")
    for i in range(5):
        yield i
        print("繼續執行")
num = intNum() 

由此,我們就成功建立了一個 num

生成器物件。顯然,和普通函式不同,intNum()函式的返回值用的是 yield 關鍵字,
而不是 return 關鍵字,此類函式又成為生成器函式。和 return 相比,yield 除了可以返回相應的值,
還有一個更重要的功能,即每當程式執行完該語句時,程式就會暫停執行。不僅如此,即便呼叫生成器函式,
Python 直譯器也不會執行函式中的程式碼,它只會返回一個生成器(物件)。

要想使生成器函式得以執行,或者想使執行完 yield 語句立即暫停的程式得以繼續執行,有以下 2 種方式:

  • 通過生成器(上面程式中的 num)呼叫 next() 內建函式或者 next() 方法;
  • 通過 for 迴圈遍歷生成器。

例如,在上面程式的基礎上,新增如下語句:


#呼叫 next() 內建函式
print(next(num))
#呼叫 __next__() 方法
print(num.__next__())
#通過for迴圈遍歷生成器
for i in num:
    print(i)

程式執行結果為:
開始執行
0
繼續執行
1
繼續執行
2
繼續執行
3
繼續執行
4
繼續執行

執行流程:

  1. 首先,在建立有 num 生成器的前提下,通過其呼叫 next() 內建函式,會使 Python 直譯器開始執行 intNum() 生成器函式中的程式碼,因此會輸出“開始執行”,程式會一直執行到yield i,而此時的 i==0,因此 Python 直譯器輸出“0”。由於受到 yield 的影響,程式會在此處暫停。

  2. 然後,我們使用 num 生成器呼叫 next() 方法,該方法的作用和 next() 函式完全相同(事實上,next() 函式的底層執行的也是 next() 方法),它會是程式繼續執行,即輸出“繼續執行”,程式又會執行到yield i,此時 i==1,因此輸出“1”,然後程式暫停。

  3. 最後,我們使用 for 迴圈遍歷 num 生成器,之所以能這麼做,是因為 for 迴圈底層會不斷地呼叫 next() 函式,使暫停的程式繼續執行,因此會輸出後續的結果。

除此之外,還可以使用 list() 函式和 tuple() 函式,直接將生成器能生成的所有值儲存成列表或者元組的形式。例如:


num = intNum()
print(list(num))
num = intNum()
print(tuple(num))

開始執行
繼續執行
繼續執行
繼續執行
繼續執行
繼續執行
[0, 1, 2, 3, 4]
開始執行
繼續執行
繼續執行
繼續執行
繼續執行
繼續執行
(0, 1, 2, 3, 4)
通過輸出結果可以判斷出,list() 和 tuple() 底層實現和 for 迴圈的遍歷過程是類似的
相比迭代器,生成器最明顯的優勢就是節省記憶體空間,即它不會一次性生成所有的資料,而是什麼時候需要,什麼時候生成。