Python使用生成器輕松處理海量數(shù)據(jù)
不知道大家有沒有處理過海量數(shù)據(jù),就是數(shù)據(jù)量非常龐大的時候,如何處理?說實在的在實際項目中確實是沒有處理過海量數(shù)據(jù),但是沒事兒的時候我們可以在本地模擬海量數(shù)據(jù)來玩玩兒的,那么處理海量數(shù)據(jù)用什么方式呢?用readlines()讀取?還是用生成器和迭代器呢?恐怕大家用的應(yīng)該也都是生成器和迭代器吧!要不然程序卡死不說,有可能把電腦搞崩潰呦!
那么生成器和迭代器怎么玩兒呢?咱們繼續(xù)往下走著看著。
從生活場景理解迭代器
想象一下你去吃自助餐,不是一次性把所有的食物都端到你桌上那得多大的桌子??!,而是想吃的時候去取一點。迭代器就是這樣的工作方式。(PS:有的人可能就是一次性端上來,個例個例,比喻不是很恰當(dāng))
在Python中,任何實現(xiàn)了__iter__()和__next__()方法的對象都是迭代器。它不會一次性把所有數(shù)據(jù)加載到內(nèi)存中,而是按需"生成"每個元素。
Python中很多內(nèi)置對象都是可迭代的:列表、元組、字符串、字典,甚至文件對象。這就是為什么你能用for循環(huán)遍歷它們的原因。
生成器:更優(yōu)雅的迭代器
寫迭代器需要定義類并實現(xiàn)兩個方法,有點麻煩。于是Python提供了更簡單的工具——生成器。
生成器有兩種創(chuàng)建方式:
1. 生成器函數(shù):使用def定義,但用yield代替return
def num_generator(num):
for i in range(num):
print(f"生成數(shù)字是:{i}")
yield i
# 使用創(chuàng)建的生成器
gen_a = num_generator(5)
# 逐個獲取值
for num in gen_a:
print(f"接收到:{num}")

2. 生成器表達式:類似列表推導(dǎo)式,但用圓括號
print("列表推導(dǎo)式VS生成器表達式:")
# 列表推導(dǎo)式-立即創(chuàng)建所有元素
list_comp = [x ** 2 for x in range(100000)]
# print(f"列表推導(dǎo)式:{list_comp}")
print(f"內(nèi)存占用:{list_comp.__sizeof__()}字節(jié)")
# 生成器表達式-按需生成元素
gen_comp = (x ** 2 for x in range(100000))
# print(f"生成器表達式:{gen_comp}")
print(f"內(nèi)存占用:{gen_comp.__sizeof__()}字節(jié)")

看看海量數(shù)據(jù)時,這個內(nèi)存占用大不大?害怕不害怕?
這個時候問題就來了:為什么生成器能高效處理大數(shù)據(jù)?為什么呢?
為什么生成器能高效處理大數(shù)據(jù)
這個主要就是生成器的一個執(zhí)行機制:
- 普通函數(shù):一旦調(diào)用,就從頭跑到尾(return),然后全部執(zhí)行完畢,局部變量全部銷毀。
- 生成器函數(shù)(使用
yield的函數(shù):如上面的第一幅截圖):調(diào)用時返回一個生成器對象,但并不立即執(zhí)行函數(shù)體。當(dāng)?shù)谝淮握{(diào)用next()時,函數(shù)從開始處執(zhí)行,直到遇到yield語句,暫停并返回 yield 后的值。函數(shù)當(dāng)前的整個局部狀態(tài)(變量、指針等)都會被凍結(jié)保存。 下次再調(diào)用next(),函數(shù)從上次暫停的yield語句后緊接著繼續(xù)執(zhí)行。
但是注意
生成器只能遍歷一次,如需重復(fù)使用需要重新創(chuàng)建,就是只能遍歷一次,再次打印已空空如也

生成器的高級用法
生成器不僅能產(chǎn)出數(shù)據(jù),還能通過send()方法接收數(shù)據(jù):
def interactive_generator():
while True:
received = yield # 等待發(fā)送數(shù)據(jù)
print(f"收到:{received}")
gen = interactive_generator()
next(gen) # 啟動生成器
gen.send("Hello") # 輸出:收到:Hello
gen.send("World") # 輸出:收到:World
這種方法在復(fù)雜的數(shù)據(jù)流水線處理中非常有用。
生成器和迭代器是Python處理海量數(shù)據(jù)的"神器",它們通過惰性計算(需要時才生成值)節(jié)省了大量內(nèi)存。 數(shù)據(jù)量不大時,用列表更簡單直接; 處理GB級別以上數(shù)據(jù)時,一定要用生成器;管道式數(shù)據(jù)處理中,生成器可以串聯(lián)形成高效處理鏈。
到此這篇關(guān)于Python使用生成器輕松處理海量數(shù)據(jù)的文章就介紹到這了,更多相關(guān)Python處理數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django中日期時間型字段進行年月日時分秒分組統(tǒng)計
這篇文章主要介紹了Django中日期時間型字段進行年月日時分秒分組統(tǒng)計,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
python文件操作seek()偏移量,讀取指正到指定位置操作
這篇文章主要介紹了python文件操作seek()偏移量,讀取指正到指定位置操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
python爬蟲開發(fā)之Beautiful Soup模塊從安裝到詳細(xì)使用方法與實例
這篇文章主要介紹了python爬蟲開發(fā)之Beautiful Soup模塊詳細(xì)使用方法與實例,需要的朋友可以參考下2020-03-03
利用OpenCV中對圖像數(shù)據(jù)進行64F和8U轉(zhuǎn)換的方式
這篇文章主要介紹了利用OpenCV中對圖像數(shù)據(jù)進行64F和8U轉(zhuǎn)換的方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
Opencv中的cv2.calcHist()函數(shù)的作用及返回值說明
這篇文章主要介紹了Opencv中的cv2.calcHist()函數(shù)的作用及返回值說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11
基于Python 的進程管理工具supervisor使用指南
Supervisor 是基于 Python 的進程管理工具,可以輕松管理一些需要以守護進程方式執(zhí)行的程序,也就是后臺任務(wù),例如用來啟動和管理基于 Tornado 寫的 Web 程序。2016-09-09

