python3 第十八章 - 迭代器與生成器

一、迭代器(Iterator)app

  • 迭代是訪問集合元素的一種方式
  • 迭代器是一個能夠記住遍歷的位置的對象。
  • 迭代器對象從集合的第一個元素開始訪問,直到全部的元素被訪問完結束。迭代器只能往前不會後退。
  • 迭代器有兩個基本的方法:iter() 和 next()。

 

字符串,列表或元組對象均可用於建立迭代器:函數

實例1:spa

basket = ['apple', 'orange', 'pear', 'banana'] it = iter(basket)  # 建立迭代器對象

# 輸出迭代器的下一個元素
print(next(it)) # 輸出迭代器的下一個元素
print(next(it))

以上代碼,輸出:code

apple orange

 

實例2:對象

basket = 'abc' it = iter(basket)  # 建立迭代器對象

print(next(it))  # 輸出迭代器的下一個元素

print(next(it))  # 輸出迭代器的下一個元素

以上代碼,輸出:blog

a b

 

一般會和for語句搭配使用,如:內存

basket = 'abc' it = iter(basket)  # 建立迭代器對象
for n in it: print(n)

以上代碼,輸出:ci

a b c

 

Python中 list,truple,str,dict這些均可以被迭代,但他們並非迭代器。爲何?字符串

由於和迭代器相比有一個很大的不一樣,list/truple/map/dict這些數據的大小是肯定的,也就是說有多少是可知的。但迭代器不是,迭代器不知道要執行多少次,因此能夠理解爲不知道有多少個元素,每調用一次next(),就會往下走一步,是惰性的。generator

 

判斷是否是能夠迭代,用Iterable

from collections import Iterable print('{} 是Iterable?', isinstance({}, Iterable)) print('() 是Iterable?', isinstance((), Iterable)) print('100 是Iterable?', isinstance(100, Iterable))

以上代碼,輸出:

{} 是Iterable? True () 是Iterable? True 100 是Iterable? False

 

 判斷是否是迭代器,用Iterator

from collections import Iterator print('{} 是Iterable?', isinstance({}, Iterator)) print('() 是Iterable?', isinstance((), Iterator)) print('(x for x in range(10)) 是Iterable?', isinstance((x for x in range(10)), Iterator))

 以上代碼,輸出:

{} 是Iterable? False () 是Iterable? False (x for x in range(10)) 是Iterable? True

凡是能夠for循環的,都是Iterable

凡是能夠next()的,都是Iterator

集合數據類型如list,truple,dict,str,都是Itrable不是Iterator,但能夠經過iter()函數得到一個Iterator對象

Python中的for循環就是經過next實現的

for x in [1, 2, 3, 4, 5]: pass

 等價於

# 先獲取iterator對象 
it = iter([1, 2, 3, 4, 5]) while True: try: # 獲取下一個值 
        x = next(it) except StopIteration: # 遇到StopIteration就退出循環 
        break

 

 

二、生成器

在 Python 中,使用了 yield 的函數被稱爲生成器(generator)。

  • 跟普通函數不一樣的是,生成器是一個返回迭代器的函數,只能用於迭代操做,更簡單點理解生成器就是一個迭代器。
  • 在調用生成器運行的過程當中,每次遇到 yield 時函數會暫停並保存當前全部的運行信息,返回yield的值。並在下一次執行 next()方法時從當前位置繼續運行。
def fibonacci(n):  # 生成器函數 - 斐波那契
    a, b, counter = 0, 1, 0 while True: if counter > n: return
        yield a a, b = b, a + b counter += 1 f = fibonacci(10)  # f 是一個迭代器,由生成器返回生成

什麼狀況下須要使用 yield?一個函數 f,f 返回一個 list,這個 list 是動態計算出來的(無論是數學上的計算仍是邏輯上的讀取格式化),而且這個 list 會很大(不管是固定很大仍是隨着輸入參數的增大而增大),這個時候,咱們但願每次調用這個函數並使用迭代器進行循環的時候一個一個的獲得每一個 list 元素而不是直接獲得一個完整的 list 來節省內存,這個時候 yield 就頗有用。

相關文章
相關標籤/搜索