python 迭代器與生成器 區別

2021-08-29 03:06:53 字數 4122 閱讀 8203

不錯的講解,生成器是一類特殊的迭代器,在迴圈遍歷自定義容器物件時,會使用python內建函式iter()呼叫遍歷物件的_iter_(self)獲得乙個迭代器,之後再迴圈對這個迭代器使用next()呼叫迭代器物件的_next_(self) 。

python中生成器和迭代器的區別(**在python3.5下測試):

定義:對於list、string、tuple、dict等這些容器物件,使用for迴圈遍歷是很方便的。在後台for語句對容器物件呼叫iter()函式。iter()是python內建函式。 iter()函式會返回乙個定義了next()方法的迭代器物件,它在容器中逐個訪問容器內的元素。next()也是python內建函式。在沒有後續元素時,next()會丟擲乙個stopiteration異常,通知for語句迴圈結束。

迭代器是用來幫助我們記錄每次迭代訪問到的位置,當我們對迭代器使用next()函式的時候,迭代器會向我們返回它所記錄位置的下乙個位置的資料。實際上,在使用next()函式的時候,呼叫的就是迭代器物件的_next_方法(python3中是物件的_next_方法,python2中是物件的next()方法)。所以,我們要想構造乙個迭代器,就要實現它的_next_方法。但這還不夠,python要求迭代器本身也是可迭代的,所以我們還要為迭代器實現_iter_方法,而_iter_方法要返回乙個迭代器,迭代器自身正是乙個迭代器,所以迭代器的_iter_方法返回自身self即可。

2,可迭代物件:實現了迭代器協議物件。list、tuple、dict都是iterable(可迭代物件),但不是iterator(迭代器物件)。但可以使用內建函式iter(),把這些都變成iterable(可迭代器物件)。

3,for item in iterable 迴圈的本質就是先通過iter()函式獲取可迭代物件iterable的迭代器,然後對獲取到的迭代器不斷呼叫next()方法來獲取下乙個值並將其賦值給item,當遇到stopiteration的異常後迴圈結束

python自帶容器物件案例:

# 隨便定義乙個list

listarray=[1,2,3]

# 使用iter()函式

itername=iter(listarray)

print(itername)

# 結果如下:是乙個列表list的迭代器

# print(next(itername))

print(next(itername))

print(next(itername))

print(next(itername))#沒有迭代到下乙個元素,直接丟擲異常

# 1# 2

# 3# traceback (most recent call last):

# file "test07.py", line 32, in # stopiteration

---------------------

python中乙個實現了_iter_方法和_next_方法的類物件,就是迭代器,如下案例是計算菲波那切數列的案例

class fib(object):

def __init__(self, max):

super(fib, self).__init__()

self.max = max

def __iter__(self):

self.a = 0

self.b = 1

return self

def __next__(self):

fib = self.a

if fib > self.max:

raise stopiteration

self.a, self.b = self.b, self.a + self.b

return fib

# 定義乙個main函式,迴圈遍歷每乙個菲波那切數

def main():

# 20以內的數

fib = fib(20)

for i in fib:

print(i)

# 測試

if __name__ == '__main__':

main()

解釋說明:

在本類的實現中,定義了乙個_iter_(self)方法,這個方法是在for迴圈遍歷時被iter()呼叫,返回乙個迭代器。因為在遍歷的時候,是直接呼叫的python內建函式iter(),由iter()通過呼叫_iter_(self)獲得物件的迭代器。有了迭代器,就可以逐個遍歷元素了。而逐個遍歷的時候,也是使用內建的next()函式通過呼叫物件的_next_(self)方法對迭代器物件進行遍歷。所以要實現_iter_(self)和_next_(self)這兩個方法。

而且因為實現了_next_(self)方法,所以在實現_iter_(self)的時候,直接返回self就可以。

總結一句話就是: 

在迴圈遍歷自定義容器物件時,會使用python內建函式iter()呼叫遍歷物件的_iter_(self)獲得乙個迭代器,之後再迴圈對這個迭代器使用next()呼叫迭代器物件的_next_(self)。

注意點:_iter_(self)只會被呼叫一次,而_next_(self)會被呼叫 n 次,直到出現stopiteration異常。

作用:>延遲操作。也就是在需要的時候才產生結果,不是立即產生結果。

注意事項:

>生成器是只能遍歷一次的。

>生成器是一類特殊的迭代器。

分類:第一類:生成器函式:還是使用 def 定義函式,但是,使用yield而不是return語句返回結果。yield語句一次返回乙個結果,在每個結果中間,掛起函式的狀態,以便下次從它離開的地方繼續執行。

如下案例加以說明:

# 菲波那切數列

def fib(max):

n, a, b = 0, 0, 1

while n < max:

yield b

a, b = b, a + b

n = n + 1

return '親!沒有資料了...'

# 呼叫方法,生成出10個數來

f=fib(10)

# 使用乙個迴圈捕獲最後return 返回的值,儲存在異常stopiteration的value中

while true:

try:

x=next(f)

print("f:",x)

except stopiteration as e:

print("生成器最後的返回值是:",e.value)

break

第二類:生成器表示式:類似於列表推導,只不過是把一對大括號變換為一對小括號()。但是,生成器表示式是按需產生乙個生成器結果物件,要想拿到每乙個元素,就需要迴圈遍歷。

如下案例加以說明:

# 乙個列表

xiaoke=[2,3,4,5]

# 生成器generator,類似於list,但是是把改為()

gen=(a for a in xiaoke)

for i in gen:

print(i)

#結果是:23

45# 為什麼要使用生成器?因為效率。

# 使用生成器表示式取代列表推導式可以同時節省 cpu 和 記憶體(ram)。

# 如果你構造乙個列表(list)的目的僅僅是傳遞給別的函式,

# 比如 傳遞給tuple()或者set(), 那就用生成器表示式替代吧!

# 本案例是直接把列表轉化為元組

kk=tuple(a for a in xiaoke)

print(kk)

#結果是:

(2, 3, 4, 5)

# python內建的一些函式,可以識別這是生成器表示式,外面有一對小括號,就是生成器

result1=sum(a for a in range(3))

print(result1)

# 列表推導式

result2=sum([a for a in range(3)])

print(result2)

python 迭代器與生成器 區別

不錯的講解,生成器是一類特殊的迭代器,在迴圈遍歷自定義容器物件時,會使用python內建函式iter 呼叫遍歷物件的 iter self 獲得乙個迭代器,之後再迴圈對這個迭代器使用next 呼叫迭代器物件的 next self python中生成器和迭代器的區別 在python3.5下測試 定義 對...

Python生成器與迭代器

生成器只有在用的時候會出現在記憶體中,對比列表全部存在記憶體中,減少了記憶體占用 next 函式 依次取生成器的值 s x 2 for x in range 1000 中括號是列表解析,小括號表示生成一系列值,就是生成器 s at 0x7fa20aa8b048 print next s 用next ...

python 迭代器與生成器

迭代器和生成器 print 1 in 1,2,3 print 1 not in 1,2,3 print 4 in print 4 not in 1,2,3 print x not in dlkjfxfei 可迭代物件 iterable 可以被next 函式呼叫並不斷返回下乙個值 知道沒有資料時丟擲s...