Python之可迭代物件 迭代器 生成器

2022-08-13 16:57:17 字數 3682 閱讀 1333

在使用python的過程中,很容易混淆如下幾個關聯的概念:

1.容器(container)

2.可迭代物件(iterable)

3.迭代器(iterator)

4.生成器(generator)

5.生成器表示式

6. 解析式

它們之間的關係如下表所示:

容器是用來儲存元素的一種資料結構,它支援隸屬測試,容器將所有資料儲存在記憶體中,在python中典型的容器有:

list, deque, …

set,frozesets,…

dict, defaultdict, ordereddict, counter, …

tuple, namedtuple, …

str容器相對來說很好理解,因為你可以把它當成生活中的箱子、房子、船等等。

一般的,通過判斷乙個物件是否包含某個元素來確定它是否為乙個容器。例如:

字典容器通過檢查是否包含鍵來進行判斷:

字串通過檢查是否包含某個子 串來判斷:

注意:並非所有的容器都是可迭代物件。

可迭代物件

正如前面所提到的,大部分容器都是可迭代的,但是還有其他一些物件也可以迭代,例如,檔案物件以及管道物件等等,容器一般來說儲存的元素是有限的,同樣的,可迭代物件也可以用來表示乙個包含有限元素的資料結構。

可迭代物件可以為任意物件,不一定非得是基本資料結構,只要這個物件可以返回乙個iterator。聽起來可能有點費解,但是可迭代物件與迭代器之間有乙個顯著的區別。先看下面的例子

注意:可迭代的類中,一般實現以下兩個方法,__iter__()以及__next()__方法,__iter__()方法返回self。

當我們執行以下**的時候:

x = [1,2,3]

for elem in x:

實際呼叫過程如下:

當我們反向編譯這段代python碼的時候,可以發現它顯示呼叫了 get_iter,本質上跟呼叫iter(x)一樣,而for_iter指令相等於呼叫next()方法來獲取每個元素。

>>> import dis

>>> x = [1,2,3]

>>> dis.dis('for _ in x: pass')

1           0 setup_loop              12 (to 14)

2 load_name                0 (x)

4 get_iter

>>   

6 for_iter                 4 (to

12)8 store_name               1 (_)

10 jump_absolute            6

>>   12 pop_block

>>   14 load_const               0 (none)

16 return_value

迭代器(iterators)

那麼什麼是迭代器呢?任何具有__next__()方法的物件都是迭代器,對迭代器呼叫next()方法可以獲取下乙個值。而至於它使如何產生這個值的,跟它能否成為乙個迭代器並沒有關係。所以迭代器本質上是乙個產生值的工廠,每次向迭代器請求下乙個值,迭代器都會進行計算出相應的值並返回。

迭代器的例子很多,例如,所有itertools模組中的函式都會返回乙個迭代器,有的還可以產生無窮的序列。

有的函式根據有限序列中生成無限序列:

>>> from itertools import cycle

>>> colors =

cycle(["red","white","blue"])

>>> next(colors)

"red"

>>> next(colors)

"white"

>>> next(colors)

"blue"

>>> next(colors)

"red"

有的函式根據無限序列中生成有限序列:

>>> from itertools import islice

>>> colors = cycle(['red', 'white',

'blue'])     # infinite

>>> limited=islice(colors,0,

4)            # finite

>>> for x in

limited:                #

so safe to use for-loop on

...            print(x)

redwhite

blue

red為了更好的理解迭代器的內部結構,我們先來定義乙個生成斐波拉契數的迭代器:

>>> class fib:

...            

def __init__(self):

...                  

self.prev = 0

...                  

self.curr = 1

...            

def __iter__(self):

...                  

return self

...            

def __next__(self):

...                  

value = self.curr

...                  

self.curr += self.prev

...                  

self.prev = value

...                  

return value

>>> f = fib()

>>> list(islice(f, 0, 10))

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

注意這個類既是可迭代的 (因為具有__iter__()方法),也是它自身的迭代器(因為具有__next__()方法)。

修改狀態,以便下次呼叫next()方法

計算當前呼叫的結果

比喻:從外部來看,迭代器就像**工作人員一樣,沒人找他辦事的時候(請求值),工作人員就閒著,當有人來找他的時候(請求值),工作人員就會忙一會,把請求的東西找出來交給請求的人。忙完之後,又沒事了,繼續閒著。

生成器

生成器其實就是一種特殊的迭代器。它shi一種更為高階、更為優雅的迭代器。

使用生成器讓我們可以以一種更加簡潔的語法來定義迭代器。

讓我們先明確以下兩點:

任意生成器都是迭代器(反過來不成立)

任意生成器,都是乙個可以延遲建立值的工廠

下面也是乙個生成斐波那契序列的工廠函式,不過是以生成器的方式編寫的:

生成器的型別

在python中兩種型別的生成器:生成器函式以及生成器表示式。生成器函式就是包含yield引數的函式。生成器表示式與列表解析式類似。

Python之可迭代物件 迭代器

python的特色之一是基於協議實現功能。比如改變乙個加號 的行為,在c 中需要操作符過載,在python中則是重寫 add 方法。為了描述可迭代物件和迭代器,python提供了兩個魔法方法,分別是 iter 和 next 又為了支援for.in.行為,牽扯進了 getitem 眾所周知使用for迴...

PYTHON 迭代器 可迭代物件

通過重複執行的 處理相似的資料集的過程,並且本次迭代的處理資料要依賴上一次的結果繼續往下做,上一次產生的結果為下一次產生結果的初始狀態,如果中途有任何停頓,都不能算是迭代。1 非迭代例子 loop 0 while loop 3 print hello world loop 1 2 迭代例子 loop...

python迭代 可迭代物件與迭代器物件

問題舉例 某軟體要求,從網路抓取各個城市的氣溫資訊,並依次顯示 北京 15 22 上海 18 23 如果一次抓取所有城市氣溫資訊再顯示,顯示第乙個城市的氣溫時會由很長的延時,並且浪費儲存空間,我們期望以 用時訪問 的策略,並且把所有城市的氣溫資訊封裝 到乙個物件裡,可用for語句進行迭代。來個栗子 ...