1. 程式人生 > >Python:迭代器、生成器(yield)、iter函式

Python:迭代器、生成器(yield)、iter函式

# 首先理解迭代器(iterators),迭代器是⼀個讓程式設計師可以遍歷的⼀個容
# 器(特別是列表)的物件。然⽽,⼀個迭代器在遍歷並讀取⼀個容器的資料元素時,並不
# 會執⾏⼀個迭代。這裡有三個部分要說明:
# 可迭代物件(Iterable)
# 迭代器(Iterator)
# 迭代(Iteration)
# 可迭代物件(Iterable):⼀個可迭代物件是Python中任意的物件,只要它定義了可以返回⼀個迭代器的__iter__
# ⽅法,或者定義了可以⽀持下標索引的__getitem__⽅法。簡單說,⼀個可迭代物件,就是任意的物件,只要它能給我們提供⼀個迭代器。
# 只要它定義了⼀個next(Python2) 或者__next__⽅法。就是⼀個迭代器。
# ⽣成器也是⼀種迭代器,但只能對其迭代⼀次。這是因為他們並沒有把所有的值存在
# 記憶體中,⽽是在運⾏時⽣成值。可使用for迴圈、傳遞給任意可進行迭代的函式和結構。
# 大多數時候,生成器是以函式來實現的,並不返回一個值,而是yield(暫且叫作”生出“)一個值。
def generator_function():
"""定義一個生成器函式"""
for i in range(10):
yield i

#呼叫生成器,以證實是一個可迭代物件
# for item in generator_function():
# print(item)

# 許多Python 2⾥的標準庫函式都會返回列表,⽽Python 3都修改成了返回⽣成器,因為⽣成
# 器佔⽤更少的記憶體資源。

# 計算斐波那契數列的⽣成器
def fibon(n):
a = b = 1
for i in range(n):
yield a
a, b = b, a + b

#for x in fibon(100):
# print(x)
# 使用python的內建函式next()獲取序列的下一個元素,到最後一個元素時,會丟擲一個StopIteration的異常
# 使用for迴圈獲取序列的下一個元素時,for迴圈會自動捕捉這個異常並停止呼叫next()。
def generator_function():
for i in range(3):
yield i

# gen = generator_function()
# print(next(gen))
# print(next(gen))
# print(next(gen))
# print(next(gen)) # 驗證,使用next()函式到所有值被yield完後會丟擲一個StopIteration的異常

# 字串型別也支援迭代,但不是迭代器,如下所示
my_string = "Michael"
#next(my_string) # 不是迭代器,不能使用next()函式,丟擲TypeError。
# 但使用另一個內建函式iter()轉換後,可以使用next()函式迭代
my_iter = iter(my_string)
print(next(my_iter)) # 經過iter()內建函式轉換後,字串物件可以迭代。