Python入門系列(五)——迭代

目錄:
一、迭代器
二、生成器

一、迭代器

我們提一下先提迭代的概念:迭代即為循環(huán)遍歷,任何遍歷的過程都是可以稱作迭代。Python中序列、集合、字典、文件和生成器等都是可迭代的,任何可迭代對象都可以作用于for循環(huán)。
首先我們來借助最基本的兩個內(nèi)置函數(shù)iter() 和 next()來完成一個簡單的迭代器。

a=range(3)
it=iter(a)                  # 創(chuàng)建迭代器對象

while 1:
        print (next(it))    #輸出迭代器的下一個元素,迭代器對象從第一個元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器只能往前不會后退。

#輸出
0
1
2
Traceback (most recent call last):
    print (next(it))     
StopIteration

我們可以看到觸發(fā)了StopIteration異常,StopIteration 異常用于標(biāo)識迭代的完成,防止出現(xiàn)無限循環(huán)的情況,所以我們做如下改寫:

import sys

a=range(3)
it=iter(a)    # 創(chuàng)建迭代器對象

while 1:
    try:
      print (next(it))      #輸出迭代器的下一個元素,迭代器對象從第一個元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器只能往前不會后退。
    except StopIteration:   #我們設(shè)置在完成循環(huán)次后捕獲 StopIteration 異常來結(jié)束迭代。
        sys.exit()

#輸出
0
1
2

但,for循環(huán)卻自帶異常處理機制:

a=range(3)
it=iter(a)    # 創(chuàng)建迭代器對象

for i in  a:
      print (next(it))  

#輸出
0
1
2
類中迭代器的使用

然后我們來拓展一下關(guān)于類中的迭代器,之前大家應(yīng)該也已經(jīng)留意到了,類中是內(nèi)置了迭代器的專有方法的。

class Numbers:
    def __init__(self,n):       #構(gòu)造函數(shù),獲取參數(shù)范圍,即打印0到幾
        self.n=n
    def __iter__(self):         #實例化對象的迭代器創(chuàng)建方法
        self.a=0
        return self
    def __next__(self):         #返回迭代器對象下一個元素的方法
        if self.a <=self.n:
            res=self.a
            self.a+=1
            return res
        else:
            raise StopIteration #raise用以引發(fā)異常。一旦執(zhí)行了raise語句,raise后面的語句將不能執(zhí)行


num=Numbers(3)                  #實例化對象num
it=iter(num)                    #創(chuàng)建實例num的迭代器對象it

print(next(it))                 #輸出迭代器對象it的下一個元素
print(next(it))
print(next(it))
print(next(it))

#輸出
0
1
2
3

當(dāng)然,我們最后的輸出完全可以使用for循環(huán)將迭代器中的內(nèi)容讀出來,輸出相同。

# print(next(it))                 #輸出迭代器對象it的下一個元素
# print(next(it))
# print(next(it))
# print(next(it))

for i in it:
    print(i)

或者使用while循環(huán),不過依然要添加異常處理:

while 1:
    try:
        print(next(it))
    except StopIteration: #使用try-except語句捕捉異常
        pass              #啥也不想干,占個位

二、生成器

而生成器是一個簡單的方式來完成迭代,生成器是一個返回迭代器的函數(shù),只能用于迭代操作,更簡單點理解生成器就是一個迭代器。

覺得上面的概念太抽象?我們借助實例來解釋~幾乎所有相關(guān)教程都在扯著名的斐波那契數(shù)列,我們就不!

說起生成器的創(chuàng)建,常用兩種方法,一種是改寫列表生成式,一種是使用yield。

列表生成式

列表生成式即List Comprehensions,是Python內(nèi)置的非常簡單卻強大的可以用來創(chuàng)建list的生成式,其實我們之前就有在使用了。

a=[x for x in range(10)]
print(a)

#輸出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

顧名思義,它生成了一個列表,那么如何改寫為生成器呢?

a=(x for x in range(10))
print(type(a))

#輸出
<class 'generator'>

我們可以看到,當(dāng)前類型已經(jīng)變?yōu)?generator',即生成器類型。改寫方法就是將[ ]替換為( )
接下來我們嘗試使用一下:

a=(x for x in range(10))

while 1:
    try:
        print(next(a))
    except:
        pass

#輸出
0
1
2
3
4
5
6
7
8
9
yield

在python中,任何使用了 yield 的函數(shù)都被稱為生成器(generator)或生成器函數(shù)。

def numbers(n):             #創(chuàng)建生成器函數(shù),這已經(jīng)不是一個普通函數(shù)啦
    for i in range(n):
        yield i             #在調(diào)用生成器運行的過程中,每次遇到 yield 時函數(shù)會暫停并保存當(dāng)前所有的運行信息,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時從當(dāng)前位置繼續(xù)運行。

num=numbers(3)              #調(diào)用生成器函數(shù),返回的是一個迭代器對象,即num。

for i in  num:              #上個例子用的while,這次我們用for
    print(i)

#輸出
0
1
2

這里往上翻一下,你會發(fā)現(xiàn)它與類中迭代器的使用中的例子功能是一致的,但那里用了近20行代碼,然而生成器卻只用了三行代碼,這就是我們?yōu)槭裁凑f生成器是使用簡單的方式進行迭代。

說到底,生成器就是一種特殊的迭代器,這也就是為什么這一章節(jié)題目如此簡單:《迭代》。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容