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

Python中Generators教程的實(shí)現(xiàn)

 更新時(shí)間:2023年02月14日 14:28:17   作者:代碼輸入中...  
本文主要介紹了Python中Generators教程的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

要想創(chuàng)建一個iterator,必須實(shí)現(xiàn)一個有__iter__()和__next__()方法的類,類要能夠跟蹤內(nèi)部狀態(tài)并且在沒有元素返回的時(shí)候引發(fā)StopIteration異常.

這個過程很繁瑣而且違反直覺.Generator能夠解決這個問題.

python generator是一個簡單的創(chuàng)建iterator的途徑.前面講的那些繁瑣的步驟都可以被generator自動完成.

簡單來說,generator是一個能夠返回迭代器對象的函數(shù).

怎樣創(chuàng)建一個python generator?

就像創(chuàng)建一個函數(shù)一樣簡單,只不過不使用return 聲明,而是使用yield聲明.

如果一個函數(shù)至少包含一個yield聲明(當(dāng)然它也可以包含其他yield或return),那么它就是一個generator. 

yield和return都會讓函數(shù)返回一些東西,區(qū)別在于,return聲明徹底結(jié)束一個函數(shù),而yield聲明是暫停函數(shù),保存它的所有狀態(tài),并且后續(xù)被調(diào)用后會繼續(xù)執(zhí)行.

generator函數(shù)和普通函數(shù)的區(qū)別

  • generator函數(shù)包含一個以上的yield聲明
  • generator函數(shù)被調(diào)用的時(shí)候,會返回一個iterator對象,但是函數(shù)并不會立即開始執(zhí)行
  • __iter__()和__next__()方法被自動實(shí)現(xiàn),所以可以使用next()函數(shù)對返回的此iterator對象進(jìn)行迭代
  • 一旦一個generator 執(zhí)行到y(tǒng)ield語句,generator函數(shù)暫停,程序控制流被轉(zhuǎn)移到調(diào)用方
  • 在對generator的連續(xù)調(diào)用之間,generator的本地變量和狀態(tài)會被保存
  • 最終,generator函數(shù)終止,再調(diào)用generator會引發(fā)StopIteration異常

下面這個例子說明上述全部要點(diǎn),我們有一個名為my_gen()的函數(shù),它帶有一些yield聲明.

# A simple generator function  
def my_gen():  
    n = 1  
    print('This is printed first')  
    # Generator function contains yield statements  
    yield n  
  
    n += 1  
    print('This is printed second')  
    yield n  
  
    n += 1  
    print('This is printed at last')  
    yield n  

有趣的是,在這個例子里變量n在每次調(diào)用之間都被記住了。和一般函數(shù)不同的是,在函數(shù)yield之后本地變量沒有被銷毀,而且,generator對象只能被這樣迭代一次。

要想重復(fù)上面的過程,需要類似 a = my_gen() 這樣創(chuàng)建另一個generator對象,并對其使用next方法迭代。

注意

:我們可以對generator對象直接使用for循環(huán)。

這是因?yàn)橐粋€for循環(huán)接收一個iterator對象,且使用next()函數(shù)迭代它,當(dāng)遇到StopIteration異常的時(shí)候自動停止。

# A simple generator function  
def my_gen():  
    n = 1  
    print('This is printed first')  
    # Generator function contains yield statements  
    yield n  
  
    n += 1  
    print('This is printed second')  
    yield n  
  
    n += 1  
    print('This is printed at last')  
    yield n  
  
# Using for loop  
  
# Output:   
# This is printed first  
# 1  
# This is printed second  
# 2  
# This is printed at last  
# 3  
  
for item in my_gen():  
    print(item) 

有循環(huán)的python generator

上面的例子沒有實(shí)際的應(yīng)用意義,我們只是為了探究背后原理。

通常來說,generator都是和循環(huán)結(jié)合實(shí)現(xiàn)的,且這個循環(huán)帶有一個終止條件。

我們來看一個reverse一個字符串的例子

def rev_str(my_str):  
    length = len(my_str)  
    for i in range(length - 1,-1,-1):  
        yield my_str[i]  
  
# For loop to reverse the string  
# Output:  
# o  
# l  
# l  
# e  
# h  
for char in rev_str("hello"):  
     print(char)  

我們在for循環(huán)里面使用range()函數(shù)來獲取反向順序的index。

generator除了可以應(yīng)用于string,還可以應(yīng)用于其它類型的iterator,例如list,tuple等。

python generator 表達(dá)式

使用generator表達(dá)式可以很容易地創(chuàng)建簡單的generator。

就像lambda函數(shù)可以創(chuàng)建匿名函數(shù)一樣,generator函數(shù)創(chuàng)建一個匿名generator函數(shù)。

generator表達(dá)式的語法類似于python的list comprehension,只是方括號被替換為了圓括號而已。

list comprehension和generator表達(dá)式的主要區(qū)別在于,前者產(chǎn)生全部的list,后者每次僅產(chǎn)生一項(xiàng)。

它們有些懶惰,僅在接到請求的時(shí)候才會產(chǎn)生輸出。因此,generator表達(dá)式比list comprehension更加節(jié)省內(nèi)存。

# Initialize the list  
my_list = [1, 3, 6, 10]  
  
# square each term using list comprehension  
# Output: [1, 9, 36, 100]  
[x**2 for x in my_list]  
  
# same thing can be done using generator expression  
# Output: <generator object <genexpr> at 0x0000000002EBDAF8>  
(x**2 for x in my_list)  

上面的例子中,generator表達(dá)式?jīng)]有立即產(chǎn)生需要的結(jié)果,而是在需要產(chǎn)生item的時(shí)候返回一個generator對象。

# Intialize the list  
my_list = [1, 3, 6, 10]  
  
a = (x**2 for x in my_list)  
# Output: 1  
print(next(a))  
  
# Output: 9  
print(next(a))  
  
# Output: 36  
print(next(a))  
  
# Output: 100  
print(next(a))  
  
# Output: StopIteration  
next(a)  

generator表達(dá)式可以在函數(shù)內(nèi)部使用。當(dāng)這樣使用的時(shí)候,圓括號可以丟棄。

python里為什么要使用generator?

1.容易實(shí)現(xiàn)

相對于iterator類來說,generator的實(shí)現(xiàn)清晰、簡潔。下面是用iterator實(shí)現(xiàn)一個2的指數(shù)函數(shù)

class PowTwo:  
    def __init__(self, max = 0):  
        self.max = max  
  
    def __iter__(self):  
        self.n = 0  
        return self  
  
    def __next__(self):  
        if self.n > self.max:  
            raise StopIteration  
  
        result = 2 ** self.n  
        self.n += 1  
        return result  

generator這樣實(shí)現(xiàn)

def PowTwoGen(max = 0):  
    n = 0  
    while n < max:  
        yield 2 ** n  
        n += 1  

因?yàn)間enerator自動跟蹤實(shí)現(xiàn)細(xì)節(jié),因此更加清晰、簡潔。

2.節(jié)省內(nèi)存

一個函數(shù)返回一個序列(sequence)的時(shí)候,會在內(nèi)存里面把這個序列構(gòu)建好再返回。如果這個序列包含很多數(shù)據(jù)的話,就過猶不及了。

而如果序列是以generator方式實(shí)現(xiàn)的,就是內(nèi)存友好的,因?yàn)樗看沃划a(chǎn)生一個item。

3.代表無限的stream

generator是一個很棒的表示無限數(shù)據(jù)流的工具。無限數(shù)據(jù)流不能被保存在內(nèi)存里面,并且因?yàn)間enerator每次產(chǎn)生一個item,它就可以表示無限數(shù)據(jù)流。

下面的代碼可以產(chǎn)生所有的奇數(shù)

def all_even():  
    n = 0  
    while True:  
        yield n  
        n += 2  

4.generator流水線(pipeline)

generator可以對一系列操作執(zhí)行流水線操作。

假設(shè)我們有一個快餐連鎖店的日志。日志的第四列是每小時(shí)售出的披薩數(shù)量,我們想對近5年的這一數(shù)據(jù)進(jìn)行求和。

假設(shè)所有數(shù)據(jù)都是字符,不可用的數(shù)據(jù)都以"N/A"表示,使用generator可以這樣實(shí)現(xiàn)

with open('sells.log') as file:  
    pizza_col = (line[3] for line in file)  
    per_hour = (int(x) for x in pizza_col if x != 'N/A')  
    print("Total pizzas sold = ",sum(per_hour))  

這個流水線既高效又易讀,并且看起來很酷!:)

到此這篇關(guān)于Python中Generators教程的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python Generators內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python使用functools實(shí)現(xiàn)注解同步方法

    Python使用functools實(shí)現(xiàn)注解同步方法

    這篇文章主要介紹了Python使用functools實(shí)現(xiàn)注解同步方法,非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • Django 限制訪問頻率的思路詳解

    Django 限制訪問頻率的思路詳解

    這篇文章主要介紹了Django 限制訪問頻率的思路詳解,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • python使用正則表達(dá)式的search()函數(shù)實(shí)現(xiàn)指定位置搜索功能

    python使用正則表達(dá)式的search()函數(shù)實(shí)現(xiàn)指定位置搜索功能

    SEARCH函數(shù),函數(shù)名。主要用來返回指定的字符串在原始字符串中首次出現(xiàn)的位置 ,從左到右查找,忽略英文字母的大小寫。接下來通過本文給大家介紹python使用正則表達(dá)式的search()函數(shù)實(shí)現(xiàn)指定位置搜索功能,需要的朋友一起看看吧
    2017-11-11
  • Python Matplotlib繪制動畫的代碼詳解

    Python Matplotlib繪制動畫的代碼詳解

    使用matplotlib可以很容易地創(chuàng)建動畫框架。在本文中我們就將利用Matplotlib制作幾個簡單的動畫,文中的示例代碼講講詳細(xì),感興趣的可以了解下
    2022-05-05
  • Python面向?qū)ο箢惖睦^承實(shí)例詳解

    Python面向?qū)ο箢惖睦^承實(shí)例詳解

    這篇文章主要介紹了Python面向?qū)ο箢惖睦^承,結(jié)合實(shí)例形式詳細(xì)分析了Python面向?qū)ο蟪绦蛟O(shè)計(jì)中類的繼承原理、定義、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2018-06-06
  • numpy展平數(shù)組ndarray.flatten()詳解

    numpy展平數(shù)組ndarray.flatten()詳解

    這篇文章主要介紹了numpy展平數(shù)組ndarray.flatten()詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Python argparse 解析命令行參數(shù)模塊詳情

    Python argparse 解析命令行參數(shù)模塊詳情

    這篇文章主要介紹了Python argparse 解析命令行參數(shù)模塊詳情,argparse是python用于解析命令行參數(shù)和選項(xiàng)的標(biāo)準(zhǔn)模塊,用于代替已經(jīng)過時(shí)的optparse模塊
    2022-07-07
  • python3圖片轉(zhuǎn)換二進(jìn)制存入mysql

    python3圖片轉(zhuǎn)換二進(jìn)制存入mysql

    MYSQL是支持把圖片存入數(shù)據(jù)庫的,也相應(yīng)的有一個專門的字段BLOB (Binary Large Object),即較大的二進(jìn)制對象字段,看下面代碼
    2013-12-12
  • python等間距取值方式

    python等間距取值方式

    這篇文章主要介紹了python等間距取值方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • keras 特征圖可視化實(shí)例(中間層)

    keras 特征圖可視化實(shí)例(中間層)

    今天小編就為大家分享一篇keras 特征圖可視化實(shí)例(中間層),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01

最新評論