-
Notifications
You must be signed in to change notification settings - Fork 94
03 LambdaLazy
本章討論了 Python 中延遲求值 (Lazy Evaluation) 的概念,並展示了它如何解決在遞迴計算中可能導致的問題。為此,我們將比較兩個範例程式,分別為未使用延遲求值的 no_lazy.py 和使用延遲求值的 lazy.py。
在 no_lazy.py 中,我們定義了一個簡單的條件函數 IF,並用它來實現階層函數 FACTORIAL。
檔案內容:no_lazy.py
def IF(cond, job_true, job_false):
if cond:
return job_true
else:
return job_false
print(f'IF(True, "Yes", "No") = {IF(True, "Yes", "No")}')
# 階層 FACTORIAL(n) = n!
def FACTORIAL(n):
return IF(n == 0, 1, n * FACTORIAL(n - 1))
print(f'FACTORIAL(3) = {FACTORIAL(3)}')-
IF的工作原理:
IF(cond, job_true, job_false)是一個簡單的條件函數,直接返回job_true或job_false的值。 -
問題出現:
當FACTORIAL(n)遞迴到n == 0時,IF的第三個參數n * FACTORIAL(n - 1)會被立即計算,即使條件cond不為真。這導致了不必要的遞迴執行,進而導致程式崩潰 (stack overflow)。
$ python no_lazy.py
IF(True, "Yes", "No") = Yes
Traceback (most recent call last):
...
RecursionError: maximum recursion depth exceeded在 lazy.py 中,我們對 IF 的邏輯進行改進,改用 Lambda 函數 將參數包裝起來,使其在條件成立時才執行相關計算。
檔案內容:lazy.py
def IF(cond, job_true, job_false):
if cond:
return job_true()
else:
return job_false()
# 階層 FACTORIAL(n) = n!
def FACTORIAL(n):
return IF(n == 0, lambda: 1, lambda: n * FACTORIAL(n - 1))
print(f'FACTORIAL(3) = {FACTORIAL(3)}')
print(f'FACTORIAL(5) = {FACTORIAL(5)}')-
延遲求值的實現:
使用 Lambda 函數 (lambda) 將job_true和job_false包裝起來,僅當對應條件成立時才執行計算。 -
如何解決問題:
當條件cond為True時,job_true()才會執行;若為False,則執行job_false()。因此,避免了遞迴過程中不必要的計算,從而成功執行。
$ python lazy.py
FACTORIAL(3) = 6
FACTORIAL(5) = 120-
提升效能:
延遲求值避免了條件分支中不必要的計算,尤其在深度遞迴或計算密集的情況下,顯著提升效能。 -
解決遞迴問題:
在FACTORIAL的實現中,未使用延遲求值會導致遞迴深度超過限制,而延遲求值則有效解決了這一問題。
延遲求值 (Lazy Evaluation) 是函數式程式設計中的一個重要概念,通過將計算的執行推遲到必要時才進行,我們能夠避免不必要的開銷,並且在處理遞迴問題時特別有效。通過 Lambda 函數的靈活使用,我們能輕鬆實現延遲求值並解決實際問題。
從希爾伯特到圖靈的那些故事
-- 以 Python 展現這些故事背後的程式