Python?迭代器和生成器概念及場(chǎng)景分析
迭代器的介紹
迭代器的定義:迭代器(Iterator)是 Python 中用于遍歷數(shù)據(jù)集合的核心機(jī)制。它提供了一種統(tǒng)一的方式來(lái)訪問(wèn)容器(如列表、字典、文件等)中的元素,而無(wú)需關(guān)心底層數(shù)據(jù)結(jié)構(gòu)的具體實(shí)現(xiàn)。迭代器的核心特點(diǎn)是按需生成數(shù)據(jù),避免一次性加載所有數(shù)據(jù)到內(nèi)存。
迭代器適合處理大型數(shù)據(jù)、無(wú)限序列或需要惰性計(jì)算的場(chǎng)景。
迭代器的核心概念:
迭代器協(xié)議:
- 一個(gè)對(duì)象要成為迭代器,必須實(shí)現(xiàn)以下兩個(gè)方法:
__iter__():返回迭代器對(duì)象本身(通常直接return self)。__next__():返回下一個(gè)元素,若沒(méi)有更多元素則拋出StopIteration異常。
- Python 的
for循環(huán)、next()函數(shù)等底層都依賴這一協(xié)議。
- 一個(gè)對(duì)象要成為迭代器,必須實(shí)現(xiàn)以下兩個(gè)方法:
可迭代對(duì)象(Iterable) VS 迭代器(Iterator):
差異體現(xiàn)在遍歷機(jī)制:
- 可迭代對(duì)象:實(shí)現(xiàn)了
__iter__()方法,可以返回一個(gè)迭代器的對(duì)象(如列表、元組、字典)。 - 迭代器:實(shí)現(xiàn)了
__iter__()和__next__()方法的對(duì)象。 - 所有迭代器都是可迭代對(duì)象,但可迭代對(duì)象本身不一定是迭代器。
- 可迭代對(duì)象:實(shí)現(xiàn)了
可迭代對(duì)象:
每次調(diào)用 iter() 會(huì)生成新的迭代器,因此可被多次遍歷:
my_list = [1, 2, 3] for x in my_list: print(x) # 輸出 1,2,3 for x in my_list: print(x) # 再次輸出 1,2,3
迭代器:
遍歷是一次性的,遍歷完成后無(wú)法重置:
iterator = iter(my_list) for x in iterator: print(x) # 輸出 1,2,3 for x in iterator: print(x) # 無(wú)輸出(迭代器已耗盡)
自定義迭代器
示例 1: 通過(guò)類實(shí)現(xiàn)迭代器
class CountUpTo:
def __init__(self, max_num):
self.max_num = max_num
self.current = 0
def __iter__(self):
return self # 返回迭代器本身
def __next__(self):
if self.current < self.max_num:
self.current += 1
return self.current
else:
raise StopIteration # 終止迭代
# 使用自定義迭代器
counter = CountUpTo(3)
for num in counter:
print(num) # 輸出 1, 2, 3示例 2: 通過(guò)生成器函數(shù)實(shí)現(xiàn)(簡(jiǎn)化版)
生成器函數(shù)(使用 yield)是創(chuàng)建迭代器的快捷方式:
def count_up_to(max_num):
current = 0
while current < max_num:
current += 1
yield current
# 生成器返回的也是迭代器
for num in count_up_to(3):
print(num) # 輸出 1, 2, 3省略的迭代器
寫過(guò)for循環(huán)的都知道,我沒(méi)用迭代器呀!
用了!只不過(guò)是編譯器幫你用了。
以下兩段代碼完全等價(jià):
# 直接遍歷列表
my_list = [1, 2, 3, 4, 5]
for x in my_list:
print(x)# 等價(jià)的手動(dòng)迭代器操作
iterator = iter(my_list) # 自動(dòng)調(diào)用 __iter__() 獲取迭代器
while True:
try:
x = next(iterator) # 自動(dòng)調(diào)用 __next__()
print(x)
except StopIteration:
break # 自動(dòng)處理終止為什么不需要顯式寫迭代器?
語(yǔ)法糖(Syntactic Sugar):for 循環(huán)是 Python 提供的一種簡(jiǎn)化語(yǔ)法,隱藏了迭代器的創(chuàng)建和異常處理細(xì)節(jié)。
統(tǒng)一接口:所有可迭代對(duì)象(如列表、元組、字典、集合、字符串等)都可以通過(guò) for 循環(huán)統(tǒng)一處理,無(wú)需關(guān)心底層是列表還是其他數(shù)據(jù)結(jié)構(gòu)。
生產(chǎn)器的介紹
yield是個(gè)英文動(dòng)詞,也是名詞,含義是生產(chǎn)的意思。

yield 在 Python里就是生成器。
yield的定義:Python 的 yield 關(guān)鍵字用于定義生成器函數(shù)(Generator Function),生成器是一種特殊的迭代器,能夠按需生成值并暫停/恢復(fù)執(zhí)行狀態(tài)。它的核心特性是惰性求值(Lazy Evaluation),適用于處理大數(shù)據(jù)流、無(wú)限序列或需要節(jié)省內(nèi)存的場(chǎng)景。
核心概念:
生成器函數(shù):
- 使用
yield代替return的函數(shù)。 - 調(diào)用生成器函數(shù)時(shí),返回一個(gè)生成器對(duì)象(迭代器),而非直接執(zhí)行函數(shù)體。
- 生成器通過(guò)
next()或for循環(huán)逐步執(zhí)行,每次遇到yield時(shí)暫停,返回yield后的值,并在下次調(diào)用時(shí)從暫停處繼續(xù)執(zhí)行。
- 使用
與普通函數(shù)的區(qū)別:
- 普通函數(shù)一次執(zhí)行完畢,返回一個(gè)結(jié)果。
- 生成器函數(shù)逐步產(chǎn)生多個(gè)值,并在
yield處保持狀態(tài)。
與 return 的區(qū)別:
| 特性 | yield | return |
|---|---|---|
| 返回值數(shù)量 | 可多次返回值 | 僅返回一次 |
| 函數(shù)狀態(tài) | 暫停并保留狀態(tài) | 終止函數(shù)執(zhí)行 |
| 返回類型 | 生成器對(duì)象(迭代器) | 直接返回值 |
| 內(nèi)存占用 | 低(按需生成) | 高(一次性生成所有數(shù)據(jù)) |
yield的普通用法
示例 1: 簡(jiǎn)單生成器
def simple_generator():
yield 1
yield 2
yield 3
gen = simple_generator()
print(next(gen)) # 輸出 1
print(next(gen)) # 輸出 2
print(next(gen)) # 輸出 3
# 繼續(xù)調(diào)用 next(gen) 會(huì)拋出 StopIteration 異常示例 2: 用 for 循環(huán)遍歷生成器
def count_up_to(n):
i = 0
while i < n:
yield i
i += 1
for num in count_up_to(5):
print(num) # 輸出 0, 1, 2, 3, 4yield的高級(jí)用法
通過(guò) send() 傳遞值生成器可以通過(guò) send(value) 接收外部傳入的值,賦值給 yield 表達(dá)式:
def generator_with_send():
value = yield "Ready to receive"
yield f"Received: {value}"
gen = generator_with_send()
print(next(gen)) # 輸出 "Ready to receive"
print(gen.send("Hello")) # 輸出 "Received: Hello"yield from 委托生成Python 3.3+ 引入 yield from,用于簡(jiǎn)化嵌套生成器的操作:
def sub_generator(): yield "A" yield "B" def main_generator(): yield from sub_generator() yield "C" for item in main_generator(): print(item) # 輸出 A, B, C
異常處理生成器可以通過(guò) throw() 方法接收異常:
def generator_with_exception(value): try: yield 10 / value except ZeroDivisionError as e: yield "Caught ValueError" gen = generator_with_exception(2) print(next(gen)) gen = generator_with_exception(0) print(next(gen))
out:
5.0
Caught ValueError
yidle的實(shí)際應(yīng)用案例
大數(shù)據(jù)處理:
def read_large_file(file_path):
with open(file_path, "r") as file:
for line in file:
yield line.strip() # 逐行生成,避免一次性加載到內(nèi)存
for line in read_large_file("data.txt"):
process(line)生成無(wú)限序列:
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
print([next(fib) for _ in range(10)]) # 前10個(gè)斐波那契數(shù)協(xié)程(Coroutine):
def coroutine():
while True:
task = yield
print(f"Processing: {task}")
worker = coroutine()
next(worker) # 啟動(dòng)協(xié)程
worker.send("Task1") # 輸出 "Processing: Task1"
worker.send("Task2") # 輸出 "Processing: Task2"在 Python 中,協(xié)程(Coroutine) 是一種可以暫停和恢復(fù)執(zhí)行的函數(shù),它能與調(diào)用方進(jìn)行雙向通信(接收和發(fā)送數(shù)據(jù)),常用于實(shí)現(xiàn)協(xié)作式多任務(wù)(非搶占式任務(wù)切換)。
上文提供的代碼是一個(gè)典型的基于生成器的協(xié)程(Generator-based Coroutine)。
總結(jié)
yield 是 Python 中實(shí)現(xiàn)惰性計(jì)算和協(xié)程的核心工具,結(jié)合 send()、throw()、close() 等方法,能夠構(gòu)建高效、靈活的數(shù)據(jù)流和控制流模型。
到此這篇關(guān)于Python 迭代器和生成器概念的文章就介紹到這了,更多相關(guān)Python 迭代器和生成器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
django前端頁(yè)面下拉選擇框默認(rèn)值設(shè)置方式
這篇文章主要介紹了django前端頁(yè)面下拉選擇框默認(rèn)值設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
Python?的矩陣傳播機(jī)制Broadcasting和矩陣運(yùn)算
這篇文章主要介紹了Python?的矩陣傳播機(jī)制Broadcasting和矩陣運(yùn)算,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06
python如何利用matplotlib繪制并列雙柱狀圖并標(biāo)注數(shù)值
Python之中最好的圖表庫(kù)叫matplotlib,matplotlib,顧名思義就是提供了一整套和matlab相似的API,它的文檔相當(dāng)完備,下面這篇文章主要給大家介紹了關(guān)于python如何利用matplotlib繪制并列雙柱狀圖并標(biāo)注數(shù)值的相關(guān)資料,需要的朋友可以參考下2022-04-04
Python實(shí)現(xiàn)將羅馬數(shù)字轉(zhuǎn)換成普通阿拉伯?dāng)?shù)字的方法
這篇文章主要介紹了Python實(shí)現(xiàn)將羅馬數(shù)字轉(zhuǎn)換成普通阿拉伯?dāng)?shù)字的方法,簡(jiǎn)單分析了羅馬數(shù)字的構(gòu)成并結(jié)合實(shí)例形式給出了Python轉(zhuǎn)換羅馬數(shù)字為阿拉伯?dāng)?shù)字的實(shí)現(xiàn)方法,需要的朋友可以參考下2017-04-04
Python爬蟲(chóng)爬取電影票房數(shù)據(jù)及圖表展示操作示例
這篇文章主要介紹了Python爬蟲(chóng)爬取電影票房數(shù)據(jù)及圖表展示操作,結(jié)合實(shí)例形式分析了Python爬蟲(chóng)爬取、解析電影票房數(shù)據(jù)并進(jìn)行圖表展示操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2020-03-03
淺談SciPy中的optimize.minimize實(shí)現(xiàn)受限優(yōu)化問(wèn)題
今天小編就為大家分享一篇淺談SciPy中的optimize.minimize實(shí)現(xiàn)受限優(yōu)化問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02

