真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

python中迭代器與生成器有什么區(qū)別

這篇文章給大家介紹python中迭代器與生成器有什么區(qū)別,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

成都創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的銅陵網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

python中迭代器與生成器有什么區(qū)別

python中生成器和迭代器的區(qū)別(代碼在Python3.5下測試):


迭代器


定義:
      對于list、string、tuple、dict等這些容器對象,使用for循環(huán)遍歷是很方便的。在后臺for語句對容器對象調(diào)用iter()函數(shù)。iter()是python內(nèi)置函數(shù)。 iter()函數(shù)會返回一個定義了next()方法的迭代器對象,它在容器中逐個訪問容器內(nèi)的元素。next()也是python內(nèi)置函數(shù)。在沒有后續(xù)元素時,next()會拋出一個StopIteration異常,通知for語句循環(huán)結(jié)束。

迭代器是用來幫助我們記錄每次迭代訪問到的位置,當我們對迭代器使用next()函數(shù)的時候,迭代器會向我們返回它所記錄位置的下一個位置的數(shù)據(jù)。實際上,在使用next()函數(shù)的時候,調(diào)用的就是迭代器對象的_next_方法(Python3中是對象的_next_方法,Python2中是對象的next()方法)。所以,我們要想構(gòu)造一個迭代器,就要實現(xiàn)它的_next_方法。但這還不夠,python要求迭代器本身也是可迭代的,所以我們還要為迭代器實現(xiàn)_iter_方法,而_iter_方法要返回一個迭代器,迭代器自身正是一個迭代器,所以迭代器的_iter_方法返回自身self即可。

一些術(shù)語的解釋:
1,迭代器協(xié)議:對象需要提供next()方法,它要么返回迭代中的下一項,要么就引起一個StopIteration異常,以終止迭代。

2,可迭代對象:實現(xiàn)了迭代器協(xié)議對象。list、tuple、dict都是Iterable(可迭代對象),但不是Iterator(迭代器對象)。但可以使用內(nèi)建函數(shù)iter(),把這些都變成Iterable(可迭代器對象)。

3,for item in Iterable 循環(huán)的本質(zhì)就是先通過iter()函數(shù)獲取可迭代對象Iterable的迭代器,然后對獲取到的迭代器不斷調(diào)用next()方法來獲取下一個值并將其賦值給item,當遇到StopIteration的異常后循環(huán)結(jié)束

Python自帶容器對象案例:

# 隨便定義一個list
listArray=[1,2,3]
# 使用iter()函數(shù)
iterName=iter(listArray)
print(iterName)
# 結(jié)果如下:是一個列表list的迭代器
# 

print(next(iterName))
print(next(iterName))
print(next(iterName))
print(next(iterName))#沒有迭代到下一個元素,直接拋出異常
# 1
# 2
# 3
# Traceback (most recent call last):
#   File "Test07.py", line 32, in 
# StopIteration
---------------------


Python中一個實現(xiàn)了_iter_方法和_next_方法的類對象,就是迭代器,如下案例是計算菲波那切數(shù)列的案例

class Fib(object):
    def __init__(self, max):
        super(Fib, self).__init__()
        self.max = max

    def __iter__(self):
        self.a = 0
        self.b = 1
        return self

    def __next__(self):
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib

# 定義一個main函數(shù),循環(huán)遍歷每一個菲波那切數(shù)
def main():
    # 20以內(nèi)的數(shù)
    fib = Fib(20)
    for i in fib:
        print(i)

# 測試
if __name__ == '__main__':
    main()


解釋說明:

在本類的實現(xiàn)中,定義了一個_iter_(self)方法,這個方法是在for循環(huán)遍歷時被iter()調(diào)用,返回一個迭代器。因為在遍歷的時候,是直接調(diào)用的python內(nèi)置函數(shù)iter(),由iter()通過調(diào)用_iter_(self)獲得對象的迭代器。有了迭代器,就可以逐個遍歷元素了。而逐個遍歷的時候,也是使用內(nèi)置的next()函數(shù)通過調(diào)用對象的_next_(self)方法對迭代器對象進行遍歷。所以要實現(xiàn)_iter_(self)和_next_(self)這兩個方法。

而且因為實現(xiàn)了_next_(self)方法,所以在實現(xiàn)_iter_(self)的時候,直接返回self就可以。

總結(jié)一句話就是: 
在循環(huán)遍歷自定義容器對象時,會使用python內(nèi)置函數(shù)iter()調(diào)用遍歷對象的_iter_(self)獲得一個迭代器,之后再循環(huán)對這個迭代器使用next()調(diào)用迭代器對象的_next_(self)。

注意點:_iter_(self)只會被調(diào)用一次,而_next_(self)會被調(diào)用 n 次,直到出現(xiàn)StopIteration異常。

生成器

作用:
>延遲操作。也就是在需要的時候才產(chǎn)生結(jié)果,不是立即產(chǎn)生結(jié)果。
注意事項:
>生成器是只能遍歷一次的。
>生成器是一類特殊的迭代器。
分類:
第一類:生成器函數(shù):還是使用 def 定義函數(shù),但是,使用yield而不是return語句返回結(jié)果。yield語句一次返回一個結(jié)果,在每個結(jié)果中間,掛起函數(shù)的狀態(tài),以便下次從它離開的地方繼續(xù)執(zhí)行。

如下案例加以說明:

# 菲波那切數(shù)列
def Fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return '親!沒有數(shù)據(jù)了...'
# 調(diào)用方法,生成出10個數(shù)來
f=Fib(10)
# 使用一個循環(huán)捕獲最后return 返回的值,保存在異常StopIteration的value中
while  True:
    try:
        x=next(f)
        print("f:",x)
    except StopIteration as e:
        print("生成器最后的返回值是:",e.value)
        break


第二類:生成器表達式:類似于列表推導,只不過是把一對大括號[]變換為一對小括號()。但是,生成器表達式是按需產(chǎn)生一個生成器結(jié)果對象,要想拿到每一個元素,就需要循環(huán)遍歷。

如下案例加以說明:

# 一個列表
xiaoke=[2,3,4,5]
# 生成器generator,類似于list,但是是把[]改為()
gen=(a for a  in xiaoke)
for  i  in gen:
    print(i)
#結(jié)果是:
2
3
4
5

# 為什么要使用生成器?因為效率。
# 使用生成器表達式取代列表推導式可以同時節(jié)省 cpu 和 內(nèi)存(RAM)。
# 如果你構(gòu)造一個列表(list)的目的僅僅是傳遞給別的函數(shù),
# 比如 傳遞給tuple()或者set(), 那就用生成器表達式替代吧!

# 本案例是直接把列表轉(zhuǎn)化為元組
kk=tuple(a for a in xiaoke)
print(kk)
#結(jié)果是:
(2, 3, 4, 5)

# python內(nèi)置的一些函數(shù),可以識別這是生成器表達式,外面有一對小括號,就是生成器
result1=sum(a for a in range(3))
print(result1)
# 列表推導式
result2=sum([a for a in range(3)])
print(result2)

關(guān)于python中迭代器與生成器有什么區(qū)別就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


網(wǎng)頁名稱:python中迭代器與生成器有什么區(qū)別
分享鏈接:http://weahome.cn/article/pejhsh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部