1. 前言
Python 是一種語法簡潔且直觀的程式語言,但若想更有效率地處理資料,就必須理解「疊代器(iterator)」的概念。本文將從疊代器的基本概念、實際用法,到應用範例,為您詳細解說。
2. 可疊代物件與疊代器的基礎
在 Python 中,資料處理時最重要的概念之一就是 「可疊代物件(iterable)」 與 「疊代器(iterator)」。了解這兩者的差異,能幫助您掌握 for 迴圈的內部運作,以及進階的資料處理技巧。
什麼是可疊代物件?
可疊代物件(iterable) 是指可以被反覆處理的物件。在 Python 中,像是 list(串列)、tuple(元組)、dict(字典)、set(集合)以及字串等,都是可疊代物件。
您可以使用 for
迴圈依序取出這些物件中的每個元素。
# list(可疊代物件)的範例
numbers = [1, 2, 3, 4, 5]
for num in numbers:
print(num)
如上所示,串列 numbers
可以透過 for
迴圈輕鬆處理。在 Python 的 for
迴圈內部,其實是先將可疊代物件轉換成疊代器,再依序取得每個元素。
什麼是疊代器?
疊代器(iterator) 是一種用來從可疊代物件中逐一取出元素的機制或物件。在 Python 中,可以使用 iter()
函式,將可疊代物件轉換成疊代器。
numbers = [1, 2, 3, 4, 5]
iterator = iter(numbers) # 建立疊代器
print(next(iterator)) # 1
print(next(iterator)) # 2
print(next(iterator)) # 3
透過呼叫 next(iterator)
,可以依序取得串列中的元素。
3. Python 中的疊代器運作原理
在 Python 中,疊代器是透過擁有特定方法的物件來實現的。
__iter__()
與 __next__()
的角色
疊代器物件具備以下兩個特殊方法:
__iter__()
:回傳物件本身__next__()
:回傳下一個元素,若已無元素則拋出StopIteration
例外
舉例來說,若使用串列手動建立疊代器,程式碼如下:
class CustomIterator:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
value = self.current
self.current += 1
return value
# 建立疊代器
custom_iter = CustomIterator(1, 5)
for num in custom_iter:
print(num) # 依序輸出 1, 2, 3, 4
如上所示,透過自訂的疊代器類別,我們可以使用 for
迴圈依序取得資料。
4. 如何在 Python 中實作疊代器
在 Python 中,我們可以自訂疊代器的實作方式,讓資料處理更加靈活。本章將詳細介紹以下幾個主題:自訂疊代器類別的建立方式、使用生成器函式、活用生成器表達式。
建立自訂的疊代器類別
在 Python 中,只要建立一個同時擁有 __iter__()
方法與 __next__()
方法的類別,就可以成為一個疊代器。
以下範例會建立一個能從指定起始數字數到結束數字的疊代器:
class Counter:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self # 回傳自己作為疊代器
def __next__(self):
if self.current > self.end:
raise StopIteration # 結束時拋出例外
value = self.current
self.current += 1
return value
# 建立疊代器並使用 for 迴圈
counter = Counter(1, 5)
for num in counter:
print(num) # 輸出 1, 2, 3, 4, 5
重點說明:
__iter__()
方法回傳self
(因為這個類別本身就是疊代器)__next__()
方法會回傳目前的值,並將內部狀態更新為下一個值- 當沒有更多資料時,拋出
StopIteration
,通知迴圈結束
透過這種方式,我們可以自訂疊代器來進行資料流處理等各種應用。
活用生成器函式
在 Python 中,可以使用 生成器函式(generator function) 來快速建立疊代器。
透過 yield
指令,可以輕鬆產生逐步回傳的資料。
def counter(start, end):
current = start
while current <= end:
yield current # 回傳值並保留執行狀態
current += 1
# 使用生成器函式
for num in counter(1, 5):
print(num) # 輸出 1, 2, 3, 4, 5
生成器函式的優點:
- 使用
yield
可以保留狀態並在下次繼續執行 - 可以節省記憶體,逐步取得需要的資料(延遲評估)
這種方法在處理 大型資料或串流資料 時特別實用。
使用生成器表達式
Python 提供一種語法簡潔的方式來建立生成器,那就是 生成器表達式(generator expression),語法與串列生成式類似。
# 串列生成式(會一次產生所有元素並存入記憶體)
numbers_list = [x * 2 for x in range(1, 6)]
print(numbers_list) # [2, 4, 6, 8, 10]
# 生成器表達式(延遲生成元素以節省記憶體)
numbers_gen = (x * 2 for x in range(1, 6))
print(next(numbers_gen)) # 2
print(next(numbers_gen)) # 4
生成器表達式的優點:
- 比串列生成式更節省記憶體
- 只計算需要的元素,支援延遲評估
在處理大量資料時,使用生成器表達式能有效提升效能與記憶體利用率。

5. 疊代器的應用範例
透過使用疊代器,我們可以高效地實作各種資料處理功能。本章將介紹 3 個實務中常見的應用案例。
① 逐行讀取大型檔案
處理大型檔案時,若一次性讀取整個內容會佔用大量記憶體。
透過疊代器,我們可以逐行處理檔案,提升效能。
def read_large_file(file_path):
with open(file_path, "r", encoding="utf-8") as file:
for line in file:
yield line.strip() # 每行資料逐步處理
# 使用方式
for line in read_large_file("data.txt"):
print(line)
優點:
- 節省記憶體,也能處理大型檔案
- 適合用於資料串流(streaming)處理
② 產生無限序列
使用疊代器可以輕鬆產生無限長度的序列,且不會占用太多資源。
def infinite_counter(start=0):
while True:
yield start
start += 1
# 限制迴圈次數以避免無限執行
counter = infinite_counter()
for _ in range(5):
print(next(counter)) # 輸出 0, 1, 2, 3, 4
應用情境:
- 依時間推移產生資料(如時間戳記)
- 處理感測器的即時輸出資料
③ 處理資料串流(Streaming)
在從 API 或資料庫取得資料時,使用疊代器可以逐筆處理每筆資料,提升彈性與效能。
import time
def api_simulation():
for i in range(1, 6):
time.sleep(1) # 模擬 API 回應時間
yield f"Data {i}"
# 逐步取得 API 回傳資料
for data in api_simulation():
print(data)
重點:
- 可即時取得與處理資料,提升反應速度
- 減輕網路與系統資源的負擔
6. 使用疊代器時的注意事項
Python 的疊代器非常實用,但若使用方式不當,可能會出現預期外的行為。本章將說明使用疊代器時應注意的 三個重點:「StopIteration 的處理」「疊代器的不可重複使用」「記憶體效率與延遲評估」。
① StopIteration 的處理方式
當使用 next()
操作疊代器並取完所有元素後,系統會拋出 StopIteration
例外。
numbers = [1, 2, 3]
iterator = iter(numbers)
print(next(iterator)) # 1
print(next(iterator)) # 2
print(next(iterator)) # 3
print(next(iterator)) # 會拋出 StopIteration
建議的處理方式是使用 try-except
來捕捉這個例外。
numbers = [1, 2, 3]
iterator = iter(numbers)
while True:
try:
print(next(iterator))
except StopIteration:
print("疊代器已經結束")
break
補充說明:
- 使用
for
迴圈時,StopIteration
會自動處理,不需手動處理 - 手動使用
next()
時,建議使用try-except
以避免錯誤
② 疊代器無法重複使用
在 Python 中,疊代器一旦被取用完畢,就無法重複使用。
numbers = [1, 2, 3]
iterator = iter(numbers)
for num in iterator:
print(num) # 輸出 1, 2, 3
for num in iterator:
print(num) # 不會有任何輸出(疊代器已經耗盡)
若要再次使用疊代器,您需要重新建立一個新的疊代器。
numbers = [1, 2, 3]
# 建立新的疊代器
iterator1 = iter(numbers)
iterator2 = iter(numbers)
print(list(iterator1)) # [1, 2, 3]
print(list(iterator2)) # [1, 2, 3]
補充說明:
- list 等可疊代物件可以重複使用,但疊代器本身只能使用一次
- 如需再次使用,請重新呼叫
iter()
③ 記憶體效率與延遲評估
使用疊代器或生成器可以大幅降低記憶體使用量,實現更有效率的資料處理。
以下範例比較 list 與 generator 的差異:
# 使用 list(會將所有元素儲存在記憶體中)
numbers_list = [x * 2 for x in range(1000000)] # 一百萬筆資料
# 使用生成器(僅在需要時才生成元素)
numbers_gen = (x * 2 for x in range(1000000))
print(sum(numbers_list)) # 計算總和,list 仍佔用記憶體
print(sum(numbers_gen)) # 計算總和但節省記憶體
補充說明:
- list 會將所有資料一次放入記憶體,適用於小型資料
- 生成器 採用延遲評估(lazy evaluation),只在需要時才生成元素
7. 常見問題(FAQ)
最後,我們整理了關於 Python 疊代器的一些常見問題與解答。
Q1. 疊代器與生成器有什麼不同?
A:
- 疊代器是實作了
__iter__()
和__next__()
方法的類別 - 生成器是使用
yield
關鍵字撰寫的函式,可以自動建立疊代器 - 使用生成器可以讓程式碼更簡潔、更易讀
Q2. 為什麼需要 __iter__()
和 __next__()
方法?
A:
__iter__()
是 Python 在使用for
迴圈時會呼叫的方法,用來取得疊代器物件__next__()
是用來取得下一個元素的方法- 因為 Python 的
for
迴圈內部就是靠iter()
與next()
來運作的
Q3. 使用疊代器有什麼優點?
A:
- 記憶體使用效率高(特別適合處理大量資料)
- 支援延遲評估(只在需要時才產生資料)
- 非常適合串流資料處理(例如處理 API 回應或檔案逐行讀取)
Q4. 什麼情況下需要手動實作疊代器?
A:
- 當您需要自訂資料處理邏輯(例如:只回傳符合特定條件的資料)
- 處理串流資料,例如從 API 即時取得資料
- 需要產生無限序列時(例如持續計數)
Q5. 疊代器與 for
迴圈的關係是什麼?
A:
for
迴圈會自動呼叫iter()
來取得疊代器,並使用next()
逐一取出元素for
也會自動處理StopIteration
的例外,因此不容易出錯
總結
在本文中,我們深入介紹了 Python 中的疊代器,從基礎概念到實際應用,幫助你全面掌握這個強大功能。
以下是重點回顧:
✅ 疊代器是一種可逐步取出資料的物件
✅ 只要實作 __iter__()
與 __next__()
方法,就能建立自訂的疊代器
✅ 使用生成器(yield
)可以更簡單地實作疊代器
✅ 透過延遲評估(lazy evaluation),疊代器能大幅提升記憶體效率
✅ 在處理 API 回應、串流資料、檔案操作等場景特別實用
掌握 Python 的疊代器後,您將能以更高效、更靈活的方式處理資料。建議您親自動手實作範例程式碼,進一步加深理解與應用能力!