可迭代物件
如果實現了__iter__
方法,就認為物件是可迭代的. 使用內建的iter函式可以獲取迭代器的物件.
- 檢查物件x是否為迭代器,最好的方式是 呼叫 isinstance(x, abc.Iterator)
- 序列都是可迭代的
迭代器(Iterator):
- 迭代器是一個物件,它實現了 iter() 和 next() 兩個基本方法。
- iter() 方法返回迭代器物件本身,用於判斷一個物件是否是一個迭代器。
- next() 方法返回迭代器的下一個元素。
- 迭代器允許你逐個訪問序列中的元素,直到所有元素都被訪問完畢。
- 迭代器可以是任何實現了這兩個方法的物件,例如列表、元組、字典、集合等。
生成器(Generator):
- 生成器是一種特殊的迭代器,它使用 yield 語句來產生值。
- 生成器是使用函式定義的,當函式中出現 yield 語句時,它就變成一個生成器。
- 當生成器函式被呼叫時,它返回一個生成器物件,而不是直接執行。生成器函式是生成器的工廠
- 每次呼叫生成器的 next() 方法時,生成器函式會從上次 yield 語句處恢復執行,直到再次遇到 yield 語句或函式結束。
- 生成器非常適合處理大資料集或無限序列,因為它不需要一次性將所有資料載入到記憶體中。
區別:
- 記憶體使用:生成器通常比迭代器更節省記憶體,因為它們可以按需生成資料,而不是一次性生成所有資料。
- 實現方式:迭代器可以由任何實現了 iter() 和 next() 方法的物件實現,而生成器是由包含 yield 語句的函式實現的。
- 資料來源:迭代器通常用於訪問已經存在的資料集合,而生成器用於建立新的資料序列。
- 函式和物件:迭代器是一個物件,而生成器是一個函式。
- 迭代器也是可迭代物件,但是可迭代物件不是迭代器
- 可迭代物件有一個
__iter__
方法,每次都例項化一個新的迭代器
示例:
# 迭代器示例
my_list = [1, 2, 3, 4]
for item in my_list:
print(item)
# 生成器示例
def my_generator():
yield 1
yield 2
yield 3
yield 4
gen = my_generator()
for item in gen:
print(item)
在第一個示例中,my_list 是一個列表迭代器。在第二個示例中,my_generator 是一個生成器函式,每次呼叫時都會生成一個新值。
測試問題: 用迭代器和生成器實現列表的遍歷?
迭代器和生成器都可以用於遍歷列表,但是它們的實現方式不同。下面是兩種方法的示例:
使用迭代器遍歷列表
在 Python 中,列表(以及其他內建的集合型別,如元組、字典和集合)都是迭代器。你可以直接使用 for 迴圈來遍歷它們。
# 定義一個列表
my_list = [1, 2, 3, 4, 5]
# 使用迭代器(for 迴圈)遍歷列表
for item in my_list:
print(item)
在這個例子中,my_list 本身就是一個迭代器,for 迴圈會自動呼叫 my_list 的 iter() 和 next() 方法來獲取列表中的元素。
使用生成器遍歷列表
生成器通常用於建立一個可以按需生成值的序列。如果你想要手動實現一個生成器來遍歷列表,你可以定義一個生成器函式。
# 定義一個生成器函式來遍歷列表
def list_generator(lst):
for item in lst:
yield item
# 建立一個列表
my_list = [1, 2, 3, 4, 5]
# 建立生成器物件
gen = list_generator(my_list)
# 使用生成器遍歷列表
for item in gen:
print(item)
在這個例子中,list_generator 是一個生成器函式,它接受一個列表作為引數,並使用 yield 語句逐個產生列表中的元素。當你建立 gen 物件時,它會按照 list_generator 函式的邏輯來生成值。
雖然在這個特定的例子中,使用生成器來遍歷列表可能看起來有些多餘,因為列表本身就是一個迭代器,但生成器在處理大型資料集或需要按需生成資料時非常有用。例如,如果你有一個非常大的檔案列表,你可能不想一次性將它們全部載入到記憶體中,而是希望按需處理它們,這時生成器就會非常有用。