全文共2424字,預計學習時長7分鐘
全文共2424字,預計學習時長7分鐘
圖源:Unsplash
如何使用生成器減少內存占用并讓Python代碼運行更快,關乎你“代碼人生”的生死存亡。
然而,當我剛開始學習Python生成器時,并不知道它最后會顯得如此重要。 但在學習機器學習的過程中需要編寫自定義函數時,它發揮了不可取代的作用。 生成器函數允許聲明一個類似于迭代器的函數,使得程序員可以以快速,簡便和簡潔的方式創建一個迭代器。 迭代器是一個可以進行迭代的對象,用于對一個數據容器進行抽象,使其表現得像可迭代的對象。常見的可迭代對象的一些示例有字符串、列表和字典。 生成器看起來跟函數很像,只是使用yield作為關鍵字而不是return。為了更好的理解,我們可以看一個例子:
def generate_numbers():
n = 0
while n < 3:
yield n
n += 1
- 這就是生成器函數。當被調用時,它會返回一個生成器對象:
>>>numbers = generate_numbers()
>>> type(numbers)
<class 'generator'>
- 需要注意的是理解狀態如何封裝在生成器函數的主體內。可以使用內置的next()函數來單步執行:
>>>next_number = generate_numbers()
>>> next(next_number)
0
>>> next(next_number)
1
>>> next(next_number)2
如果在結尾時繼續調用next()會發生什么?
StopIteration是一個內置的異常類型,一旦生成器停止執行yield語句,它將自動觸發。這是for循環停止的信號。
圖源:Unsplash
Yield語句
它的主要工作是以類似于return語句的方式控制生成器函數的流程。
當調用一個生成器函數或者使用生成器表達式時,會返回一個稱為生成器的特殊迭代器。可以通過將此生成器分配給變量來使用它。
當調用生成器上的特殊方法,例如next(),函數中的代碼會執行到yield語句。 當執行到達了Python代碼中的yield語句,程序就會中止函數的執行,并將產生的值返回給調用方。(相反,return會完全停止函數執行。)
當一個函數被掛起時,它的狀態會被保存。 在熟悉了Python的生成器之后,讓我們從內存使用和代碼執行花費的時間兩方面來比較普通方法與使用生成器的方法。
問題陳述
假設我們必須遍歷一大串數字(例如100000000),并將所有偶數的平方存儲在單獨的列表中。
普通方法
- importmemory_profilerimport timedef check_even(numbers): even = [] for num in numbers: if num % 2 == 0: even.append(num*num) return evenif __name__ == '__main__': m1 = memory_profiler.memory_usage() t1 = time.clock() cubes = check_even(range(100000000)) t2 = time.clock() m2 = memory_profiler.memory_usage() time_diff = t2 - t1 mem_diff = m2[0] - m1[0] print(f"It took {time_diff} Secsand {mem_diff} Mb to execute this method")
運行后,上述代碼的輸出如下:
- It took21.876470000000005 Secs and 1929.703125 Mb to execute this method
使用生成器
- importmemory_profilerimport timedef check_even(numbers): for num in numbers: if num % 2 == 0: yield num * num if __name__ == '__main__': m1 = memory_profiler.memory_usage() t1 = time.clock() cubes = check_even(range(100000000)) t2 = time.clock() m2 = memory_profiler.memory_usage() time_diff = t2 - t1 mem_diff = m2[0] - m1[0] print(f"It took {time_diff} Secsand {mem_diff} Mb to execute this method")
運行后,上述代碼的輸出如下:
- It took2.9999999995311555e-05 Secs and 0.02656277 Mb to execute this method
肉眼可見,執行時間和內存使用量都大大減少了。 生成器僅按需工作,也就是眾所周知的通過惰性評估工作。這意味著它們可以節省CPU,內存和其他計算資源。
圖源:Unsplash
今天,我們學習了如何使用python的生成器來減少內存使用并使代碼執行更快。 這種方式的優點在于,生成器不會將所有結果都存儲在內存中,而是即時生成它們,因此僅在我們請求結果時它才會使用內存。
生成器還可以抽象出編寫迭代器所需的許多樣板代碼,因此也有助于減少代碼量。
快來試試吧,一定會取得讓你驚喜不已的結果。
留言 點贊 關注
我們一起分享AI學習與發展的干貨
如需轉載,請后臺留言,遵守轉載規范


