貴州遵義疫情最新消息合肥網(wǎng)站優(yōu)化方案
Python迭代器與生成器
迭代器
什么是迭代器
首先迭代是指python中訪問元素的一種方式,迭代器是一個可以記住遍歷位置的對象,因此不會像列表那樣一次性全部生成,而是可以等到用的時候才生成,因此節(jié)省了大量的內(nèi)存資源
可迭代對象
類似于list、tuple、str 等類型的數(shù)據(jù)可以使用for循環(huán)遍歷語法從其中依次拿到數(shù)據(jù)并進行使用,我們把這個過程稱為遍歷,也稱迭代。python中可迭代的對象有list(列表)、tuple(元組)、dirt(字典)、str(字符串)set等
除此之外還可以通過instance
來判斷平常使用的字符串,列表,元組和字典等,若s是一個**Iterable(可迭代對象)**則結(jié)果返回為True
# 導(dǎo)入Iterable,Iterator模塊
from collections.abc import Iterable,Iterators = "abcdefgh"
print(isinstance(s,Iterable)) # True
print(isinstance(s,Iterator)) # Falsel = [1,2,3,4,5,6,7,8]
print(isinstance(s,Iterable)) # True
print(isinstance(s,Iterator)) # Falset = (1,2,3,4,5,6,7,8)
print(isinstance(s,Iterable)) # True
print(isinstance(s,Iterator)) # False
只是名義上的 可迭代對象/迭代器 還不夠,具有相應(yīng)的功能才算是完整。首先,對于__iter__
方法,它需要具有一個可以返回一個迭代器對象的功能(這個對象可以是自己(前提是本身就是一個迭代器),也可以是其它迭代器);對于__next__
方法,它是用于獲取迭代器(Iterator)
中的下一個元素。它的基本語法是:
迭代器的應(yīng)用
next(iterator[, default])
iterator
是要獲取下一個元素的迭代器對象。default
是一個可選參數(shù),表示在迭代器耗盡時返回的默認(rèn)值。如果不提供default
參數(shù)且迭代器耗盡,則會引發(fā)StopIteration
異常。
以下是一些next()
方法的用例
# 創(chuàng)建一個列表和迭代器對象
my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)# 逐個獲取迭代器中的元素
print(next(my_iterator)) # 輸出: 1
print(next(my_iterator)) # 輸出: 2
print(next(my_iterator)) # 輸出: 3# 使用默認(rèn)值處理迭代器耗盡的情況
print(next(my_iterator, "End")) # 輸出: 4
print(next(my_iterator, "End")) # 輸出: 5
print(next(my_iterator, "End")) # 輸出: End
next()
方法在循環(huán)中經(jīng)常被用來逐個處理迭代器中的元素,直到迭代器耗盡或滿足某個條件。這種方式可以避免一次性加載整個序列到內(nèi)存中,節(jié)省資源并提高效率
生成器
什么是生成器
生成器(generator)也是一種迭代器,在每次迭代時返回一個值,直到拋出 StopIteration異常。它有兩種構(gòu)造方式:
生成器表達式
和列表推導(dǎo)式的定義類似,生成器表達式使用 () 而不是 [] ,比如:
print((i for i in range(5)))
# <generator object <genexpr> at 0x00000235C67B9700>nums = (i for i in range(5))
for num in nums:print(num)
# 0 1 2 3 4print(isinstance(nums, Iterable)) # True 表示nums屬于可迭代對象
print(isinstance(nums, Iterator)) # True 表示nums屬于迭代器
生成器函數(shù)
含有 yield
關(guān)鍵字的函數(shù),調(diào)用該函數(shù)時會返回一個生成器。生成器對象可以通過調(diào)用其方法(例如 next()
)來逐步執(zhí)行函數(shù)體中的代碼,每次調(diào)用會產(chǎn)生一個值,并在遇到 yield
語句時暫停執(zhí)行。
def my_generator():for i in range(10):print(i)if i > 7:yield '大于7'# 使用生成器函數(shù)
gen = my_generator()
for i in gen:print(i)
# 0 1 2 3 4 5 6 7 8大于7 9大于7# __next__方法
gen = my_generator()
print(next(gen))
print(next(gen))
print(next(gen))# 0 1 2 3 4 5 6 7 8大于7 9大于7 超過最大值然后報錯
# print(next(gen))
# ^^^^^^^^^
# StopIteration
調(diào)用該函數(shù)的時候不會立即執(zhí)行代碼,而是返回了一個生成器對象;
當(dāng)使用 next() (在 for 循環(huán)中會自動調(diào)用 next() ) 作用于返回的生成器對象時,函數(shù) 開始執(zhí)行,在遇到 yield 的時候會『暫?!?#xff0c;并返回當(dāng)前的迭代值;
當(dāng)再次使用 next() 的時候,函數(shù)會從原來『暫停』的地方繼續(xù)執(zhí)行,直到遇到 yield語 句,如果沒有 yield 語句,則拋出異常
簡而言之,就是 next 使函數(shù)執(zhí)行, yield 使函數(shù)暫停
.send()方法
當(dāng)我們使用 send(value)
方法發(fā)送一個值到生成器時,該值會成為生成器函數(shù)中對應(yīng) yield
表達式的結(jié)果,并且生成器會從暫停的位置繼續(xù)執(zhí)行
def my_generator():x = yield 'Ready' # 第一次調(diào)用 send() 方法將被忽略yield f'Received: {x}'gen = my_generator()
print(next(gen)) # 輸出: 'Ready'
print(gen.send('Hello')) # 輸出: 'Received: Hello'
.close()方法
我們可以使用 close() 方法來關(guān)閉一個生成器。生成器被關(guān)閉后,再次調(diào)用 next() 方法,不管能否遇到 yield 關(guān)鍵字,都會拋出 StopIteration 異常
def my_generator():for i in range(10):print(i)if i > 7:yield '大于7'# 使用生成器函數(shù)
gen = my_generator()
gen.close() # 關(guān)閉生成器
print(next(gen))
# StopIteration 報錯