『無為則無心』Python基礎 — 61、Python中的迭代器

繁華似錦Fighting發表於2022-03-02

1、迭代的概念

(1)什麼是迭代

迭代就是單向地、逐個地訪問某個容器中的元素的行為。 簡單說迭代就是迴圈。

(2)迭代和遍歷的區別

迭代是遍歷的一種特例,遍歷(traverse)是可以在資料結構上來回的遊走,不僅可以往前,還可以往後,同時還能保證不重不漏的,迭代是單向的,逐個的,而且只來一次。

2、迭代器的概念

(1)概念

在Python中常見的序列有listtuplesetdictstr,我們也稱之為容器。

我們之前在遍歷這些容器的時候,針對不同的容器,每次寫的程式碼還都有所差別。於是我們想能不能寫一個工具,當我們需要對一個容器中的元素,進行單向的,一個接一個的取出來的時候,就呼叫這個工具。

這個工具可以幫我們把不同容器遍歷細節上的不同遮蔽掉,當我們需要這個操作的時候,就把容器直接傳給這個工具就好了,而這個工具就叫迭代器。

(2)優點

  • 從序列型別中一個一個的取值,會把所有的值都取到。
  • 節省記憶體空間,迭代器並不會在記憶體中佔用一大塊記憶體,面是隨著迴圈每次生成一個,每呼叫一次next方法就會返回給我一個元素。

3、可迭代的物件(Iterable)

(1)什麼是可迭代的物件

簡單的說,一個物件只要實現了只要實現了__iter__()方法,就是一個可迭代的物件。

可以使用isinstance()判斷一個物件是否是Iterable物件:

(2)Python中常見的可迭代資料型別

  1. 集合或序列型別(如listtuplesetdictstr
  2. 檔案物件(以後擴充套件)
  3. 在類中定義了__iter__()方法的物件,可以被認為是 Iterable物件,

示例:

from collections.abc import Iterable

print(isinstance('', Iterable))  # true 字串是可迭代的
print(isinstance([], Iterable))  # true 列表是可迭代的
print(isinstance((), Iterable))  # true 元組是可迭代的
print(isinstance({}, Iterable))  # true 字典是可迭代的
print(isinstance(set(), Iterable))  # true 集合是可迭代的

說明:

這些內建集合或序列物件都有__iter__方法,即他們都實現了同名方法。

我們可以隨便定義一個序列,如下:

testList = list()

在PyCharm中按住ctrl鍵點選list()就可以檢視list類的原始碼。

原始碼中我們就能夠看到list類中定義了__iter__函式。

其他的可迭代序列同理。

像int資料型別,按住ctrl鍵點選檢視。int類中並沒有定義__iter__函式。

1 = int()

4、迭代器物件(Iterator)

序列型別(如listtuplesetdictstr等)都是可迭代物件,但是他們並不是迭代器物件。

可以使用iter()函式把可迭代物件(Iterable)變成迭代器物件(Iterator):

驗證:

from collections.abc import Iterable, Iterator

print(isinstance('', Iterator))  # False 字串不是迭代器物件
print(isinstance([], Iterator))  # False 列表不是迭代器物件
print(isinstance((), Iterator))  # False 元組不是迭代器物件
print(isinstance({}, Iterator))  # False 字典是不是迭代器物件
print(isinstance(set(), Iterator))  # False 集合不是迭代器物件



# iter()可把對應的可迭代物件轉換成迭代器物件
print(isinstance(iter(""), Iterator))  # True 迭代器物件
print(isinstance(iter([]), Iterator))  # True 迭代器物件
print(isinstance(iter(()), Iterator))  # True 迭代器物件
print(isinstance(iter({}), Iterator))  # True 迭代器物件
print(isinstance(iter(set()), Iterator))  # True 迭代器物件

說明:

可迭代物件支援內建函式iter,通過對可迭代物件呼叫iter函式,會返回一個迭代器。而“迭代器”支援內建函式next(),通過不斷對其呼叫next()方法,會依次前進到序列中的下一個元素並將其返回,最後到達序列的末尾時,會引發StopIteration異常。

補充說明一點,對迭代器呼叫iter方法,則會返回迭代器自身。

示例如下:

# 定義一個列表
testList = [1, 2, 3, 4]

# 把列表轉變成一個迭代器物件
it = iter(testList)

# 迭代器物件呼叫__iter__,返回迭代器物件本身
# <list_iterator object at 0x0000000002674B88>
print(it.__iter__())

5、迭代器的使用體驗

(1)基本用法

# 定義一個列表
testList = [1, 2, 3, 4]

# 把列表轉變成一個迭代器物件
it = iter(testList)

# 使用迭代器
# 從迭代器中取出一個接著一個的元素
print(next(it))  # 1
print(next(it))  # 2
print(next(it))  # 3
print(next(it))  # 4
# 當迭代完儲存的所有元素之後,如果繼續迭代,
# # 則 __next__() 方法會丟擲 StopIteration 異常。
print(next(it))  # StopIterable 異常

(2)實際應用

# 示例1
# 用迭代器來訪問列表中的元素
# 定義一個列表
testList = [1, 2, 3, 4]

# 把裂變轉變成一個迭代器物件
it = iter(testList)

# 使用迭代器取值
while True:
    try:
        # 呼叫next函式,獲取下一個字元
        result = next(it)
        print(result)
    except StopIteration:
        # 釋放對it的引用,即廢棄迭代器物件
        del it
        # 不推出迴圈會成為私迴圈
        break


# 示例2
# 用迭代器來訪問列表中的元素
# 定義一個字串
testStr = "Python"

# 把裂變轉變成一個迭代器物件
it = iter(testStr)

# 使用迭代器取值
for str in it:
    print(str)

參考:

相關文章