Python - 迭代器
大家好,有志於成為 Python 程式設計師的你!今天,我們將進入 Python 迭代器的奇妙世界。身為你親切友善的電腦科學老師,我非常高興能引導你們通過這個迷人的主題。所以,拿起你 最喜歡的飲料,放鬆身心,讓我們一起深入探討!
Python 迭代器
迭代器是什麼?
想象一下,你有一個裝滿彩色樂高積木的大盒子。迭代器就像一隻神奇的手,可以伸進盒子中一次拿出 一塊樂高積木,讓你可以逐一檢查每塊積木,而不需要把整盒的東西倒在地板上。在 Python 中, 迭代器的工作方式類似,讓我們可以一次處理一個數據集合中的項目。
迭代器如何工作?
Python 的迭代器是實現了兩個特殊方法的對象:__iter__()
和 __next__()
。如果這些對你來說 看起來像胡言亂語,先別擔心——我們將一步一步來解釋!
-
__iter__()
方法返回迭代器對象本身。這就像在說,“嘿,我準備好要開始發樂高積木了!" -
__next__()
方法返回序列中的下一個項目。這就像伸手進盒子,拿出下一塊樂高積木。
讓我們透過一個簡單的例子來看看這是怎麼工作的:
# 創建一個列表(我們的樂高積木盒)
my_list = [1, 2, 3, 4, 5]
# 從列表中獲取迭代器
my_iterator = iter(my_list)
# 使用 next() 一次獲取一個項目
print(next(my_iterator)) # 輸出:1
print(next(my_iterator)) # 輸出:2
print(next(my_iterator)) # 輸出:3
在這個例子中,iter(my_list)
為我們的列表創建了一個迭代器對象。然後,每次調用 next(my_iterator)
從列表中检索下一個項目。
迭代器在循環中的威力
這裡有一個有趣的事實:當你在 Python 中使用 for
循環時,其實你是在幕後使用迭代器!讓我們看看是怎麼回事:
my_list = ["apple", "banana", "cherry"]
for fruit in my_list:
print(f"I love {fruit}!")
# 輸出:
# I love apple!
# I love banana!
# I love cherry!
Python 自動從 my_list
創建一個迭代器,並使用 __next__()
從循環中獲取每個項目。這不 是很棒嗎?
迭代器的錯誤處理
那麼,當我們的神奇樂高積木检索手伸進一個空盒子時會發生什麼?在 Python 的語境中,當迭代器中沒有更多的項目時會發生什麼?這就是錯誤處理進場的時候。
當迭代器耗盡(沒有更多的項目)時,它會引發一個 StopIteration
例外。讓我們看看這是怎麼工作的:
my_list = [1, 2, 3]
my_iterator = iter(my_list)
print(next(my_iterator)) # 輸出:1
print(next(my_iterator)) # 輸出:2
print(next(my_iterator)) # 輸出:3
print(next(my_iterator)) # 引發 StopIteration 例外
為了妥善處理這一情況,我們可以使用 try-except 區塊:
my_list = [1, 2, 3]
my_iterator = iter(my_list)
try:
while True:
item = next(my_iterator)
print(item)
except StopIteration:
print("達到迭代器結尾!")
# 輸出:
# 1
# 2
# 3
# 達到迭代器結尾!
這樣,我們可以平滑地處理所有項目並妥善處理迭代器的結尾。
自定义迭代器
現在我們已經了解了迭代器是如何工作的,讓我們來創建自己的迭代器!想象我們想要創建一個倒數計時迭代器。以下是我們可以如何做到這一點:
class Countdown:
def __init__(self, start):
self.start = start
def __iter__(self):
return self
def __next__(self):
if self.start <= 0:
raise StopIteration
self.start -= 1
return self.start + 1
# 使用我們的自定义迭代器
countdown = Countdown(5)
for number in countdown:
print(number)
# 輸出:
# 5
# 4
# 3
# 2
# 1
在這個例子中,我們創建了一個 Countdown
類,它既是一個可迭代的(它有一個 __iter__()
方法) 也是一個迭代器(它有一個 __next__()
方法)。每次調用 __next__()
時,它都會返回倒數序列中的下一個數字。
异步迭代器
當我們進入更先進的領域時,讓我們簡短地談談異步迭代器。這些用於異步編程,是一種編寫並發代碼的方法。
異步迭代器與普通迭代器類似,但它使用 async
和 await
關鍵字。以下是一個簡單的例子:
import asyncio
class AsyncCountdown:
def __init__(self, start):
self.start = start
def __aiter__(self):
return self
async def __anext__(self):
await asyncio.sleep(1) # 模拟一些異步操作
if self.start <= 0:
raise StopAsyncIteration
self.start -= 1
return self.start + 1
async def main():
async for number in AsyncCountdown(5):
print(number)
asyncio.run(main())
# 輸出(帶有 1 秒延時):
# 5
# 4
# 3
# 2
# 1
這個異步迭代器的工作方式與我們之前的 Countdown
類類似,但它允許異步操作(在這裡用 asyncio.sleep(1)
模拟)。
迭代器方法表格
以下是總結我們討論過的關鍵方法的便捷表格:
方法 | 描述 | 用於 |
---|---|---|
__iter__() |
返回迭代器對象 | 常規迭代器 |
__next__() |
返回序列中的下一個項目 | 常規迭代器 |
__aiter__() |
返回異步迭代器對象 | 異步迭代器 |
__anext__() |
返回異步序列中的下一個項目 | 異步迭代器 |
就是這樣,各位!我們已經穿越了 Python 迭代器的領域,從基礎到創建自己的迭代器,甚至還接觸了異步迭代器。記住,就像學習建造樂高一樣,掌握迭代器需要練習。所以,不要害怕實驗並建造你自己的迭代器。編程愉快,願迭代器與你同在!
Credits: Image by storyset