最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python自定義迭代器的實(shí)現(xiàn)方法

 更新時(shí)間:2026年05月29日 09:38:36   作者:一天 24h  
自定義迭代器的核心是嚴(yán)格遵守 Python 迭代器協(xié)議,只要一個(gè)類實(shí)現(xiàn)了__iter__()和__next__()這兩個(gè)特殊方法,它的實(shí)例就是一個(gè)合法的迭代器,本文給大家介紹了Python自定義迭代器的實(shí)現(xiàn)方法,需要的朋友可以參考下

引言

自定義迭代器的核心是嚴(yán)格遵守 Python 迭代器協(xié)議。只要一個(gè)類實(shí)現(xiàn)了__iter__()__next__()這兩個(gè)特殊方法,它的實(shí)例就是一個(gè)合法的迭代器。

一、迭代器協(xié)議的核心要求

任何自定義迭代器都必須滿足以下兩個(gè)條件:

  1. __iter__(self):必須返回迭代器對(duì)象本身(return self)。這是為了讓迭代器可以直接用在for循環(huán)等接受可迭代對(duì)象的地方。
  2. __next__(self)
    • 返回序列中的下一個(gè)元素
    • 更新內(nèi)部狀態(tài),指向下一個(gè)元素
    • 當(dāng)沒(méi)有更多元素時(shí),必須拋出StopIteration異常

二、第一個(gè)自定義迭代器:生成指定范圍的偶數(shù)

我們從最簡(jiǎn)單的例子開(kāi)始,實(shí)現(xiàn)一個(gè)能生成從startend之間所有偶數(shù)的迭代器:

class EvenIterator:
    def __init__(self, start, end):
        # 初始化迭代器的狀態(tài)
        self.current = start if start % 2 == 0 else start + 1  # 確保從偶數(shù)開(kāi)始
        self.end = end

    def __iter__(self):
        # 迭代器必須返回自己
        return self

    def __next__(self):
        if self.current > self.end:
            # 沒(méi)有更多元素,拋出異常終止迭代
            raise StopIteration
        # 保存當(dāng)前值
        result = self.current
        # 更新?tīng)顟B(tài),指向下一個(gè)偶數(shù)
        self.current += 2
        # 返回當(dāng)前值
        return result

使用這個(gè)迭代器

# 創(chuàng)建迭代器實(shí)例
even_iter = EvenIterator(1, 10)

# 1. 使用next()手動(dòng)遍歷
print(next(even_iter))  # 輸出:2
print(next(even_iter))  # 輸出:4
print(next(even_iter))  # 輸出:6

# 2. 直接用for循環(huán)遍歷(自動(dòng)處理next()和StopIteration)
for num in EvenIterator(1, 10):
    # end控制每個(gè)輸出的數(shù)用空格隔開(kāi),默認(rèn)是換行‘\n'
    print(num, end=' ')  # 輸出:2 4 6 8 10

三、深入理解:迭代器的工作原理

1. 為什么__iter__()必須返回 self?

因?yàn)?Python 中所有接受 "可迭代對(duì)象" 的地方(for循環(huán)、list()sum()等),都會(huì)先調(diào)用iter(對(duì)象)獲取迭代器。

如果__iter__()返回的不是 self,那么for循環(huán)拿到的就是另一個(gè)對(duì)象,而不是我們的迭代器本身,迭代邏輯就會(huì)失效。

2. 迭代器的 "一次性" 特性

迭代器的狀態(tài)是不可逆的,一旦遍歷到末尾,就無(wú)法再?gòu)念^開(kāi)始:

even_iter = EvenIterator(1, 10)

# 第一次遍歷:正常輸出
print(list(even_iter))  # 輸出:[2, 4, 6, 8, 10]

# 第二次遍歷:空列表!
print(list(even_iter))  # 輸出:[]

這是因?yàn)榈谝淮伪闅v后,self.current已經(jīng)變成了 12,再調(diào)用next()會(huì)直接拋出StopIteration。

3. 如何實(shí)現(xiàn)可多次遍歷的 "可迭代對(duì)象"?

如果需要多次遍歷,應(yīng)該將可迭代對(duì)象迭代器分開(kāi)實(shí)現(xiàn):

  • 可迭代對(duì)象:實(shí)現(xiàn)__iter__(),每次返回一個(gè)新的迭代器實(shí)例
  • 迭代器:實(shí)現(xiàn)__iter__()__next__()
# 可迭代對(duì)象(可以多次遍歷)
class EvenNumbers:
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def __iter__(self):
        # 每次調(diào)用iter()都返回一個(gè)新的迭代器
        return EvenIterator(self.start, self.end)

# 現(xiàn)在可以多次遍歷了
evens = EvenNumbers(1, 10)
print(list(evens))  # 輸出:[2, 4, 6, 8, 10]
print(list(evens))  # 輸出:[2, 4, 6, 8, 10]

四、實(shí)用自定義迭代器示例

示例 1:逆序遍歷列表的迭代器

class ReverseIterator:
    def __init__(self, data):
        self.data = data
        self.index = len(data)  # 從最后一個(gè)元素的下一個(gè)位置開(kāi)始

    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index -= 1
        return self.data[self.index]

# 使用
for char in ReverseIterator('hello'):
    print(char, end=' ')  # 輸出:o l l e h

示例 2:無(wú)限斐波那契數(shù)列迭代器

這是迭代器最強(qiáng)大的應(yīng)用之一 —— 生成無(wú)限序列

class FibonacciIterator:
    def __init__(self):
        self.a = 0
        self.b = 1

    def __iter__(self):
        return self

    def __next__(self):
        result = self.a
        self.a, self.b = self.b, self.a + self.b
        return result

# 使用:按需生成,永遠(yuǎn)不會(huì)結(jié)束
fib = FibonacciIterator()
for _ in range(15):
    print(next(fib), end=' ')  # 輸出:0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

示例 3:分批處理數(shù)據(jù)的迭代器

class BatchIterator:
    def __init__(self, data, batch_size):
        self.data = data
        self.batch_size = batch_size
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        # 計(jì)算當(dāng)前批次的結(jié)束位置
        end = self.index + self.batch_size
        # 切片獲取當(dāng)前批次
        batch = self.data[self.index:end]
        # 更新索引
        self.index = end
        return batch

# 使用
data = list(range(100))
for batch in BatchIterator(data, 10):
    print(f"處理批次:{batch}")
    # 在這里處理每一批數(shù)據(jù)

五、更簡(jiǎn)單的方式:生成器(Generator)

手動(dòng)實(shí)現(xiàn)__iter__()__next__()雖然清晰,但比較繁瑣。Python 提供了生成器,可以用更簡(jiǎn)潔的語(yǔ)法創(chuàng)建迭代器。

生成器使用yield關(guān)鍵字,自動(dòng)實(shí)現(xiàn)了迭代器協(xié)議:

# 生成器函數(shù):等價(jià)于上面的EvenIterator
def even_generator(start, end):
    current = start if start % 2 == 0 else start + 1
    while current <= end:
        yield current  # 暫停執(zhí)行,返回當(dāng)前值
        current += 2

# 使用方式和迭代器完全一樣
for num in even_generator(1, 10):
    print(num, end=' ')  # 輸出:2 4 6 8 10

生成器的優(yōu)勢(shì)

  1. 代碼更簡(jiǎn)潔:不需要定義類和兩個(gè)特殊方法
  2. 自動(dòng)管理狀態(tài):Python 會(huì)自動(dòng)保存函數(shù)的執(zhí)行狀態(tài)
  3. 可讀性更高:邏輯更直觀,更容易理解

生成器表達(dá)式

對(duì)于簡(jiǎn)單的迭代邏輯,還可以使用生成器表達(dá)式,這是創(chuàng)建迭代器的最簡(jiǎn)潔方式:

# 生成器表達(dá)式:等價(jià)于even_generator(1, 10)
even_gen = (x for x in range(1, 11) if x % 2 == 0)

print(list(even_gen))  # 輸出:[2, 4, 6, 8, 10]

六、手動(dòng)實(shí)現(xiàn) vs 生成器:如何選擇?

實(shí)現(xiàn)方式優(yōu)點(diǎn)缺點(diǎn)適用場(chǎng)景
手動(dòng)實(shí)現(xiàn)迭代器完全控制迭代邏輯,靈活性最高代碼繁瑣,容易出錯(cuò)復(fù)雜的迭代邏輯、需要維護(hù)復(fù)雜狀態(tài)
生成器函數(shù)代碼簡(jiǎn)潔,可讀性高,自動(dòng)管理狀態(tài)靈活性稍低大多數(shù)場(chǎng)景,尤其是中等復(fù)雜度的迭代邏輯
生成器表達(dá)式最簡(jiǎn)潔,一行代碼搞定只能實(shí)現(xiàn)簡(jiǎn)單邏輯簡(jiǎn)單的轉(zhuǎn)換、過(guò)濾操作

七、自定義迭代器的常見(jiàn)坑

  1. 忘記在__next__()中拋出StopIteration:會(huì)導(dǎo)致無(wú)限循環(huán)
  2. __iter__()沒(méi)有返回 self:迭代器無(wú)法用在 for 循環(huán)中
  3. 迭代器狀態(tài)沒(méi)有正確更新:會(huì)導(dǎo)致重復(fù)返回同一個(gè)元素或跳過(guò)元素
  4. 試圖多次遍歷同一個(gè)迭代器:第二次遍歷會(huì)得到空結(jié)果

八、總結(jié):自定義迭代器的步驟

  1. 定義一個(gè)類
  2. __init__()方法中初始化迭代器的狀態(tài)
  3. 實(shí)現(xiàn)__iter__()方法,返回 self
  4. 實(shí)現(xiàn)__next__()方法:
    • 檢查是否還有更多元素
    • 如果沒(méi)有,拋出StopIteration
    • 如果有,計(jì)算并返回當(dāng)前元素
    • 更新內(nèi)部狀態(tài),指向下一個(gè)元素

總而言之:自定義迭代器是 Python 迭代機(jī)制的底層核心,通過(guò)遵守迭代器協(xié)議,我們可以實(shí)現(xiàn)高效、靈活的數(shù)據(jù)遍歷。生成器是簡(jiǎn)化版的自定義迭代器,適用于大多數(shù)場(chǎng)景;而手動(dòng)實(shí)現(xiàn)類則提供了最高的靈活性,滿足復(fù)雜的迭代需求。

以上就是Python自定義迭代器的實(shí)現(xiàn)方法的詳細(xì)內(nèi)容,更多關(guān)于Python自定義迭代器實(shí)現(xiàn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python使用OCR實(shí)現(xiàn)提取掃描PDF的文本

    Python使用OCR實(shí)現(xiàn)提取掃描PDF的文本

    從 PDF 中提取文本一直是很多人的需求,本文將帶你了解如何借助 Python + OCR 技術(shù),從掃描 PDF 中提取可編輯文本,希望對(duì)大家有所幫助
    2025-09-09
  • 使用Python腳本批量搞定所有文件重命名

    使用Python腳本批量搞定所有文件重命名

    日常工作中你是不是也遇到過(guò)這種場(chǎng)景:整理旅行照片時(shí),一堆?IMG_001.jpg、IMG_002.jpg看得眼花繚亂,其實(shí)根本不用這么費(fèi)勁,今天就教你寫一個(gè)超實(shí)用的Python小腳本,30行代碼實(shí)現(xiàn)文件批量重命名,需要的朋友可以參考下
    2026-01-01
  • python十進(jìn)制和二進(jìn)制的轉(zhuǎn)換方法(含浮點(diǎn)數(shù))

    python十進(jìn)制和二進(jìn)制的轉(zhuǎn)換方法(含浮點(diǎn)數(shù))

    這篇文章主要介紹了python十進(jìn)制和二進(jìn)制的轉(zhuǎn)換方法(含浮點(diǎn)數(shù)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Python將字符串轉(zhuǎn)換為小寫字母的幾種常用方法

    Python將字符串轉(zhuǎn)換為小寫字母的幾種常用方法

    這篇文章主要介紹了Python中將字符串大寫字母轉(zhuǎn)小寫的四種方法:lower()方法簡(jiǎn)潔高效,手動(dòng)ASCII轉(zhuǎn)換靈活可控,str.translate()性能優(yōu)化適合大數(shù)據(jù)處理,列表推導(dǎo)式實(shí)現(xiàn)代碼簡(jiǎn)潔,總結(jié)方法優(yōu)缺點(diǎn)及適用場(chǎng)景,需要的朋友可以參考下
    2025-05-05
  • 請(qǐng)不要重復(fù)犯我在學(xué)習(xí)Python和Linux系統(tǒng)上的錯(cuò)誤

    請(qǐng)不要重復(fù)犯我在學(xué)習(xí)Python和Linux系統(tǒng)上的錯(cuò)誤

    本人已經(jīng)在運(yùn)維行業(yè)工作了將近十年,我最早接觸Linux是在大二的樣子,那時(shí)候只追求易懂,所以就選擇了Ubuntu作為學(xué)習(xí)、使用的對(duì)象,它簡(jiǎn)單、易用、好操作、界面絢麗,對(duì)于想接觸Linux的新手來(lái)說(shuō)是非常不錯(cuò)的
    2016-12-12
  • Python發(fā)送郵件測(cè)試報(bào)告操作實(shí)例詳解

    Python發(fā)送郵件測(cè)試報(bào)告操作實(shí)例詳解

    這篇文章主要介紹了Python發(fā)送郵件測(cè)試報(bào)告操作,結(jié)合實(shí)例形式較為詳細(xì)的分析了Python郵件發(fā)送相關(guān)模塊使用及操作注意事項(xiàng),需要的朋友可以參考下
    2018-12-12
  • Pyramid將models.py文件的內(nèi)容分布到多個(gè)文件的方法

    Pyramid將models.py文件的內(nèi)容分布到多個(gè)文件的方法

    默認(rèn)的Pyramid代碼結(jié)構(gòu)中,就只有一個(gè)models.py文件,在實(shí)際項(xiàng)目中,如果需要對(duì)models進(jìn)行分類,放到不同文件下,應(yīng)該怎么辦
    2013-11-11
  • Python中pandas庫(kù)sort_values()方法的使用

    Python中pandas庫(kù)sort_values()方法的使用

    最后去看了有關(guān)于 sort_values 的文檔,成功解決先把單詞出現(xiàn)頻次由高往低依次排序,再把頻次相同的情況下的單詞按照 MD5 值排序這個(gè)問(wèn)題,下面通過(guò)本文講解下Python中pandas庫(kù)sort_values()方法的使用,感興趣的朋友一起看看吧
    2023-07-07
  • 帶你一文讀懂Python垃圾回收機(jī)制

    帶你一文讀懂Python垃圾回收機(jī)制

    這篇文章主要介紹了帶你一文讀懂Python垃圾回收機(jī)制,如果對(duì)其垃圾回收機(jī)制不了解,很多時(shí)候?qū)懗龅?nbsp;Python 代碼會(huì)非常低效,需要的朋友可以參考下
    2023-04-04
  • Python使用re模塊正則提取字符串中括號(hào)內(nèi)的內(nèi)容示例

    Python使用re模塊正則提取字符串中括號(hào)內(nèi)的內(nèi)容示例

    這篇文章主要介紹了Python使用re模塊正則提取字符串中括號(hào)內(nèi)的內(nèi)容,結(jié)合實(shí)例形式分析了Python使用re模塊進(jìn)行針對(duì)括號(hào)內(nèi)容的正則匹配操作,并簡(jiǎn)單解釋了相關(guān)修正符與正則語(yǔ)句的用法,需要的朋友可以參考下
    2018-06-06

最新評(píng)論

灵丘县| 灌云县| 长治县| 建瓯市| 遂昌县| 霍城县| 连江县| 普定县| 郧西县| 南宫市| 南华县| 定南县| 军事| 合山市| 定远县| 开平市| 宁国市| 长乐市| 扬州市| 天门市| 定日县| 兴海县| 东丽区| 阳山县| 巧家县| 阿勒泰市| 嫩江县| 鲁甸县| 东乡| 军事| 修水县| 建阳市| 乌鲁木齐市| 仙居县| 丽江市| 苏尼特右旗| 肇庆市| 方正县| 札达县| 富裕县| 白山市|