概述
????????在上一節(jié),我們介紹了Python的模塊和包,包括:什么是模塊、導(dǎo)入模塊、自定義模塊、__name__、什么是包、創(chuàng)建包、導(dǎo)入包等內(nèi)容。在這一節(jié)中,我們將介紹Python的迭代器和生成器。在Python中,迭代器是一個(gè)非常重要的概念,它使得我們能夠遍歷一個(gè)序列而無需使用索引。迭代器不僅限于列表、元組、字符串等,我們也可以創(chuàng)建自定義的迭代器對(duì)象。生成器是一種特殊的迭代器,能夠根據(jù)需要生成數(shù)據(jù)。與傳統(tǒng)的列表、元組等不同,生成器可以在需要時(shí)才生成數(shù)據(jù),從而有效節(jié)省內(nèi)存空間。
使用迭代器
????????迭代器是Python中一個(gè)重要的設(shè)計(jì)模式。迭代器是一個(gè)能夠記住遍歷的位置的對(duì)象,可以讓我們遍歷一個(gè)容器,比如:列表、元組、字典等。Python的許多內(nèi)置數(shù)據(jù)類型,比如:列表、元組、字典、集合和字符串,都實(shí)現(xiàn)了迭代器接口??梢允褂胕ter()函數(shù)獲取這些對(duì)象的迭代器,然后使用next()函數(shù)逐個(gè)獲取元素。
info = ['hello', 'CSDN', 'python']
# 獲取迭代器
it = iter(info)
# 遍歷下一個(gè)元素,輸出:hello
print(next(it))
# 遍歷下一個(gè)元素,輸出:CSDN
print(next(it))
# 遍歷下一個(gè)元素,輸出:python
print(next(it))
????????除了使用next()函數(shù)遍歷元素外,也可以使用for語句進(jìn)行遍歷。
info = ['hello', 'CSDN', 'python']
# 獲取迭代器
it = iter(info)
# 使用for遍歷,依次輸出:hello CSDN python
for item in it:
print(item)
????????當(dāng)然,也可以使用while語句結(jié)合next()函數(shù)遍歷所有元素。此時(shí),需要額外處理StopIteration異常。這是因?yàn)?,?dāng)next()函數(shù)遍歷完序列中的所有元素后,會(huì)拋出StopIteration異常。
info = ['hello', 'CSDN', 'python']
# 獲取迭代器
it = iter(info)
# 使用while和next函數(shù)遍歷,依次輸出:hello CSDN python
while True:
try:
print(next(it))
except StopIteration:
break
創(chuàng)建迭代器
????????在Python中,可以通過定義一個(gè)包含__iter__()和__next__()函數(shù)的類來創(chuàng)建自定義的迭代器。其中,__iter__()函數(shù)返回一個(gè)特殊的迭代器對(duì)象,一般為迭代器對(duì)象本身;__next__()函數(shù)會(huì)返回序列中的下一個(gè)元素,并通過拋出StopIteration異常標(biāo)識(shí)整個(gè)迭代過程的完成。
# 自定義迭代器類
class CustomIterator:
def __init__(self):
self.value = 1
def __iter__(self):
return self
def __next__(self):
if self.value <= 6:
result = self.value
self.value += 1
return result
else:
# 遍歷結(jié)束時(shí),需要拋出StopIteration異常
raise StopIteration
# 創(chuàng)建自定義迭代器對(duì)象
cus_iter = CustomIterator()
# 遍歷自定義迭代器,依次輸出:1 2 3 4 5 6
for item in cus_iter:
print(item)
????????在上面的示例代碼中,首先定義了一個(gè)名為CustomIterator的類。這個(gè)類包含__iter__()和__next__()函數(shù)。__iter__()函數(shù)返回迭代器對(duì)象本身,而__next__()函數(shù)返回序列中的下一個(gè)元素。在__next__()函數(shù)中,檢查當(dāng)前值是否小于等于6,如果是,則返回當(dāng)前值并將值加1,否則,拋出StopIteration異常,結(jié)束遍歷。最后,我們創(chuàng)建了一個(gè)CustomIterator的實(shí)例,并使用for循環(huán)遍歷它。
創(chuàng)建生成器
????????生成器實(shí)際上是一種特殊的迭代器,通過定義一個(gè)包含yield關(guān)鍵字的函數(shù)即可創(chuàng)建生成器。yield關(guān)鍵字用于在函數(shù)執(zhí)行過程中返回一個(gè)值,并將控制權(quán)交回給調(diào)用者。當(dāng)再次調(diào)用生成器時(shí),它會(huì)從上次返回的位置繼續(xù)執(zhí)行,直到再次遇到y(tǒng)ield。通過yield,生成器函數(shù)可以逐步產(chǎn)生值,而不需要一次性計(jì)算并返回所有值,節(jié)省了內(nèi)存空間。與普通函數(shù)不同的是,生成器是一個(gè)返回迭代器的函數(shù),只能用于迭代操作。調(diào)用一個(gè)生成器函數(shù),返回的是一個(gè)迭代器對(duì)象。在下面的示例代碼中,我們定義了get_odd生成器,用于生成小于num的奇數(shù)的迭代器。
def get_odd(num):
ori = 1
while ori < num:
yield ori
ori += 2
????????生成器在處理大量數(shù)據(jù)或需要按需生成數(shù)據(jù)的場(chǎng)景中,是非常有用的。比如:在處理文本文件時(shí),我們可能不需要將整個(gè)文件一次性加載到內(nèi)存中,而是可以使用生成器逐行讀取文件。另外,在機(jī)器學(xué)習(xí)、大數(shù)據(jù)處理等領(lǐng)域,生成器也能夠發(fā)揮重要作用。
????????Python中的生成器具有以下幾個(gè)優(yōu)點(diǎn):
????????1、按需生成數(shù)據(jù),有效節(jié)省內(nèi)存空間。
????????2、能夠處理大量數(shù)據(jù),而不會(huì)導(dǎo)致內(nèi)存溢出。
????????3、可以使用簡(jiǎn)單的代碼實(shí)現(xiàn)復(fù)雜的迭代邏輯。
使用生成器
????????創(chuàng)建好生成器之后,我們就可以像使用迭代器一樣使用生成器了。以上面的get_odd生成器為例,如果我們需要輸出10以下的奇數(shù),既可以使用next()函數(shù),也可以使用for語句,示例代碼如下。文章來源:http://www.zghlxwxcb.cn/news/detail-685424.html
def get_odd(num):
ori = 1
while ori < num:
yield ori
ori += 2
odd_generator = get_odd(10)
# 輸出:1
print(next(odd_generator))
# 輸出:3
print(next(odd_generator))
# 依次輸出:5 7 9
for item in odd_generator:
print(item)
????????考慮下面的應(yīng)用場(chǎng)景:我們需要從文件中讀取大量數(shù)據(jù),并進(jìn)行相應(yīng)的處理。如果使用傳統(tǒng)的列表或元組,可能會(huì)占用大量?jī)?nèi)存。此時(shí),可以使用生成器逐行讀取文件,從而有效節(jié)省內(nèi)存。具體如何使用,可參考下面的示例代碼。文章來源地址http://www.zghlxwxcb.cn/news/detail-685424.html
def read_file(file_path):
with open(file_path, 'r', encoding='utf-8', errors='ignore') as file:
while line := file.readline():
yield line.strip()
generator = read_file('./test.py')
# 使用生成器讀取文件,并按行輸出文件內(nèi)容
for line in generator:
print(line)
到了這里,關(guān)于8 python的迭代器和生成器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!