1. 程式人生 > 其它 >16、迭代器

16、迭代器

一、迭代器介紹

  • 可迭代物件
  • 迭代器物件

二、for迴圈原理

三、迭代器的優缺點

  • 優點
  • 缺點

一 迭代器介紹

迭代器即用來迭代取值的工具,而迭代是重複反饋過程的活動,其目的通常是為了逼近所需的目標或結果,每一次對過程的重複稱為一次”迭代“,而每一次迭代得到的結果會作為下一次迭代的初始值,單純的重複並不是迭代

while Ture:
    msg = input('>>>:').strip()
    print(msg)

下述while迴圈才是一個迭代過程,不僅滿足重複,而且以每次重新賦值後的index值作為下一次迴圈中的新的索引進行取值,反覆迭代,最終可以取盡列表中的值

goods = ['mac', 'lenovo', 'acer', 'dell', 'sony']

index = 0
while index < len(goods):
    print(goods(index))
    index += 1

可迭代物件

通過索引的方式進行迭代取值,實現簡單,但僅使用於序列型別:字串,列表,元組。對於沒有索引的字典、集合等非序列型別,必須找到一種不依賴索引來進行迭代取值的方式,這就用到了迭代器。

要想了解迭代器為何物,必須事先搞清楚一個很重要的概念:可迭代物件(Iterable)。從語法形式上講,內建有__iter__方法的物件都是可迭代物件,字串、列表、元組、字典、集合、開啟的檔案都是可迭代物件:

{'name':'egon'}.__iter__
{7, 8, 9}.__iter__
......

迭代器物件

呼叫obj.iter()方法返回的結果就是一個迭代器物件(Iterator)。迭代器物件是內建有iter和next方法的物件,開啟的檔案本身就是一個迭代器物件,執行迭代器物件.iter()方法得到的仍然是迭代器本身,不依賴於索引的迭代取值方式,只要存在多個”值“,無論序列型別還是非序列型別都可以按照迭代器的方式取值

>>> s = {1, 2, 3}  # 可迭代物件s
>>> i = iter(s)  # 本質就是載呼叫s.__iter__(),返回s的迭代器物件
>>> next(i)  # 本質就是再呼叫i.__next__()
1
>>> next(i)
2
>>> next(i)
3
>>> next(i)  # 丟擲StopIteration的異常,代表無值可取,迭代結束
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

for迴圈原理

有了迭代器後,我們便可以不依賴索引迭代取值了,使用while迴圈的實現方式如下

goods = ['mac', 'lenovo', 'acer', 'dell', 'sony']
i = iter(goods)  # 每次都需要重新獲取一個迭代器物件
while Ture:
    try:
        print(next(i))
    except StopIteration:  # 捕捉異常終止迴圈
        break

for迴圈又稱為迭代迴圈,in後可以跟任意可迭代物件,上述while迴圈可以簡寫為

goods = ['mac', 'lenovo', 'acer', 'dell', 'sony']
for item in goods:
    print(item)

for迴圈再工作時,首先會呼叫可迭代物件goods內建的iter方法拿到一個迭代器物件,然後再呼叫該迭代器物件的next方法將取到的值賦給iten,執行迴圈體完成一次迴圈,周而復始,直到捕捉StopIteration異常,結束迭代。

三 迭代器的優缺點

基於索引的迭代取值,所有的狀態都儲存在了索引中,而基於迭代器實現迭代的方式不再需要索引,所有迭代的狀態就儲存在迭代器中,然而這種處理方式優點於缺點並存:

優點

  • 為序列和非序列型別提供了統一的迭代取值方式。
  • 惰性計算:迭代器物件表示的是一個數據流,可以只在需要時才去呼叫next來計算出一個值,就迭代器本身來說,同一時刻在記憶體中只有一個值,因而可以存放無限大的資料流,而對於其他容器型別,如列表,需要把所有的元素都存放於記憶體中,受記憶體大小的限制,可以存放的值的個數是有限的。

缺點

  • 除非取盡,否則無法獲取迭代器的長度
  • 只能取下一個值,不能回到開始,更像是’一次性的‘,迭代器產生後的唯一目標就是重複執行next方法直到值取盡,否則就會停留在某個位置,等待下一次呼叫next;若是要再次迭代同個物件,你只能重新呼叫iter方法去建立一個新的迭代器物件,如果有兩個或者多個迴圈使用同一個迭代器,必然只會有一個迴圈能取到值。