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

2021-10-24 12:46:00 字數 3901 閱讀 7233

可迭代物件是迭代器、生成器和裝飾器的基礎。

簡單來說,可以使用for來迴圈遍歷的物件就是可迭代物件。比如常見的list、set和dict。

我們來看乙個例子:

from collections import iterable

print

(isinstance

('abcddddd'

, iterable)

)# str是否可迭代

print

(isinstance([

1,2,

3,4,

5,6]

, iterable)

)# list是否可迭代

print

(isinstance

(12345678

, iterable)

)# 整數是否可迭代--

----

----

---結果如下---

----

----

----

-true

true

false

當對所有的可迭代物件呼叫 dir() 方法時,會發現他們都實現了iter方法。這樣就可以通過 iter(object) 來返回乙個迭代器。

x =[1

,2,3

]y =

iter

(x)print

(type

(x))

print

(type

(y))--

----

----

--結果如下---

----

----

-<

class

'list'

>

<

class

'list_iterator'

>

可以看到呼叫iter()之後,變成了乙個list_iterator的物件。可以發現增加了乙個__next__方法。所有實現了__iter__和__next__兩個方法的物件,都是迭代器。

迭代器是帶狀態的物件,它會記錄當前迭代所在的位置,以方便下次迭代的時候獲取正確的元素。__iter__返回迭代器自身,__next__返回容器中的下乙個值,如果容器中沒有更多元素了,則丟擲stoplteration異常。

x =[1

,2,3

]y =

iter

(x)print

(next

(y))

print

(next

(y))

print

(next

(y))

print

(next

(y))--

----

----結果如下---

----

---1

23traceback (most recent call last)

: file "/users/rocky/desktop/test.py"

, line 6,in

print

(next

(y))

stopiteration

如何判斷物件是否是迭代器,和判斷是否是可迭代物件的方法差不多,只要把 iterable 換成 iterator。

python的for迴圈本質上就是通過不斷呼叫next()函式實現的,舉個栗子,下面的**

x =[1

,2,3

]for elem in x:..

.

也就是先將可迭代物件轉化為iterator,再去迭代。應該是處於對記憶體的節省考慮。因為迭代器只有在我們呼叫 next() 才會實際計算下乙個值。

itertools 庫提供了很多常見迭代器的使用。

>>

>

from itertools import count # 計數器

>>

> counter = count(start=13)

>>

>

next

(counter)

13>>

>

next

(counter)

14

無限迴圈序列:

>>

>

from itertools import cycle

>>

> colors = cycle(

['red'

,'white'

,'blue'])

>>

>

next

(colors)

'red'

>>

>

next

(colors)

'white'

>>

>

next

(colors)

'blue'

>>

>

next

(colors)

'red'

我們建立列表的時候,受到記憶體限制,容量肯定是有限的,而且不可能全部給他一次列舉出來。上面的思路是使用列表生成式,但是它有乙個致命的缺點就是定義即生成,非常的浪費空間和效率。

如果列表元素可以按照某種演算法推算出來,那我們可以在迴圈的過程中不斷推算出後續的元素,這樣就不必建立完整的list,從而節省大量的空間。在python中,這種一邊迴圈一邊計算的機制,稱為生成器:generator。

要建立乙個generator,最簡單的方法是改造列表生成式:

a =

[x*x for x in

range(10

)]print

(a)b =

(x * x for x in

range(10

))print

(b)---

----

-結果如下---

----

----

---[

0,1,

4,9,

16,25,

36,49,

64,81]

at 0x10557da50

>

還有乙個方法是生成器函式,同樣是通過def定義,然後通過yield來支援迭代器協議,所以比迭代器寫起來更簡單。

def

spam()

:yield

"first"

yield

"second"

yield

"third"

for x in spam():

print

(x)---

----結果如下---

----

--first

second

third

進行函式呼叫的時候,返回乙個生成器物件。在使用next()呼叫的時候,遇到yield就返回,記錄此時的函式呼叫位置,下次呼叫next()時,從斷點處開始。

我們完全可以像使用 iterator 一樣使用 generator ,當然除了定義。定義乙個iterator,你需要分別實現iter() 方法和next() 方法,但 generator 只需要乙個小小的yield 。

generator 還有 send() 和 close() 方法,都是只能在next()呼叫之後,生成器出去掛起狀態時才能使用的。

python 是支援協程的,也就是微執行緒,就是通過 generator 來實現的。配合 generator 我們可以自定義函式的呼叫層次關係從而自己來排程執行緒。

PYTHON 迭代器 可迭代物件

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

迭代器和可迭代物件

本篇文章簡單談談可迭代物件,迭代器和生成器之間的關係。三者簡要關係圖 可迭代物件與迭代器 剛開始我認為這兩者是等同的,但後來發現並不是這樣 下面直接丟擲結論 1 可迭代物件包含迭代器。2 如果乙個物件擁有 iter 方法,其是可迭代物件 如果乙個物件擁有next方法,其是迭代器。3 定義可迭代物件,...

可迭代物件和迭代器

建立這個物件的類中是否定義了 iter 方法,如果定義了,那麼這個物件就是可迭代物件。isinstance obj,iterable 判斷 判斷乙個物件是不是迭代器的時候,需要判斷建立這個例項物件的類中是否定義了 iter 方法和 next 方法,如果都定義了,那麼這個物件就是可迭代物件。所以如果乙...