1. 程式人生 > 其它 >python的生成器和迭代器

python的生成器和迭代器

一、可迭代物件

  可用for迴圈進行迭代的物件,字串、列表、元組、集合、字典。但它們不是迭代器。

二、迭代器

  列表可以通過iter轉為迭代器,如下:

>>> x = [1, 2, 3]
>>> a = iter(x)
>>> b = iter(x)
>>> next(a)
1
>>> next(a)
2
>>> next(b)
1
>>> type(x)
<class 'list'>
>>> type(a)
<class 'list_iterator'>
>>> type(b)
<class 'list_iterator'>

  在迴圈遍歷自定義容器物件時,會使用python內建函式iter()呼叫遍歷物件的__iter__()獲得一個迭代器,之後再迴圈對這個迭代器使用next()呼叫迭代器物件的__next__()__iter__()只會被呼叫一次,而__next__()會被呼叫 n 次。

  迭代器與列表的區別在於,構建迭代器的時候,不像列表把所有元素一次性載入到記憶體,而是以一種延遲計算(lazy evaluation)方式返回元素,這正是它的優點。比如列表中含有一千萬個整數,需要佔超過100M的記憶體,而迭代器只需要幾十個位元組的空間。因為它並沒有把所有元素裝載到記憶體中,而是等到呼叫next()方法的時候才返回該元素(按需呼叫 call by need 的方式,本質上 for 迴圈就是不斷地呼叫迭代器的next()

方法)。

三、生成器

  分為兩種:生成器函式(用yield實現);生成器表示式,x = (x*x for x in range(10))。

  普通函式用return返回一個值,還有一種函式用yield返回值,這種函式叫生成器函式。函式被呼叫時會返回一個生成器物件。生成器其實是一種特殊的迭代器,不過這種迭代器更加優雅,它不需要像普通迭代器一樣實現__iter__()__next__()方法了,只需要一個yield關鍵字。生成器一定是迭代器(反之不成立),因此任何生成器也是一種懶載入的模式生成值。

  yield就是return返回一個值,並且記住這個返回的位置,下次迭代就從這個位置後(下一行)開始。next

方法和send方法都可以返回下一個元素,區別在於send可以傳遞引數給yield表示式,這時傳遞的引數會作為yield表示式的值,而yield的引數是返回給呼叫者的值。

詳情參見:https://zhuanlan.zhihu.com/p/341439647