国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中利用函數(shù)裝飾器實現(xiàn)備忘功能

2020-02-23 00:27:42
字體:
來源:轉載
供稿:網友

“備忘”的定義

“memoization”(備忘)這個詞是由Donald Michie在1968年提出的,它基于拉丁語單詞“memorandum”(備忘錄),意思是“被記住”。雖然它和單詞“memorization”在某種程度上有些相似,但它并不是該單詞的錯誤拼寫。實際上,Memoisation是一種用于通過計算來加速程序的技術,它通過記住輸入量的計算結果,例如函數(shù)調用結果,來實現(xiàn)其加速目的。如果遇到相同的輸入或者具有相同參數(shù)的函數(shù)調用,那么之前存儲的結果就可以被再次使用,從而避免一些不必要的計算。在很多情況下,可以使用一個簡單的數(shù)組來存儲結果,但也可以使用許多其他的數(shù)據結構,例如關聯(lián)數(shù)組,它在Perl語言中叫做哈希,在Python語言中稱為字典。

備忘功能可以由程序員顯式地編程實現(xiàn),但是一些編程語言如Python,都提供了自動備忘函數(shù)的機制。
利用函數(shù)裝飾器實現(xiàn)備忘功能

在前面關于遞歸函數(shù)的那章中,我們分別使用迭代和遞歸實現(xiàn)了斐波納契數(shù)列的求解。我們已經證明,如果直接利用斐波納契數(shù)列的數(shù)學定義,在一個遞歸函數(shù)中實現(xiàn)數(shù)列的求解,正如下面的函數(shù)一樣,那么它將具有指數(shù)級的時間復雜度:
 

def fib(n):  if n == 0:    return 0  elif n == 1:    return 1  else:    return fib(n-1) + fib(n-2)

此外,我們還提出了一種提高遞歸實現(xiàn)的時間復雜度的方法,即通過添加一個字典來記住之前函數(shù)的計算結果。這是一個顯式地使用備忘技術的例子,只是當時我們并沒有這么稱呼它。這種方法的缺點是,原始遞歸實現(xiàn)的明晰性和優(yōu)雅性丟失了。

造成以上缺點的原因是,我們改變了遞歸函數(shù)fib的代碼。不過下面的代碼不會改變我們的fib函數(shù),所以它的明晰性和易讀性并沒有丟失。為了實現(xiàn)該目的,我們使用自定義的函數(shù)memoize()。函數(shù)memoize()以函數(shù)作為參數(shù),并使用一個字典“memo”來存儲函數(shù)的結果。雖然變量“memo”和函數(shù)“f”僅僅具有局部備忘功能,但是它們通過函數(shù)“helper”被一個閉包捕獲,而memoize()將函數(shù)“helper”作為引用返回。所以,對memoize(fib)的調用將會返回一個helper()的引用,而在helper()中實現(xiàn)了fib()函數(shù)的功能以及一個用于保存還未存儲的結果到字典“memo”中的包裝器,并防止重新計算“memo”中已有的結果。
 

def memoize(f):  memo = {}  def helper(x):    if x not in memo:            memo[x] = f(x)    return memo[x]  return helper def fib(n):  if n == 0:    return 0  elif n == 1:    return 1  else:    return fib(n-1) + fib(n-2) fib = memoize(fib) print(fib(40))

現(xiàn)在讓我們了解下所謂的裝飾器,首先看一下上面代碼中將備忘功能指派到fib函數(shù)的這一行:

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 游戏| 广灵县| 阳城县| 师宗县| 万山特区| 峨眉山市| 兴山县| 辉县市| 杨浦区| 蒲城县| 莱州市| 翁牛特旗| 尼玛县| 梨树县| 乡宁县| 永新县| 金华市| 巧家县| 闽清县| 上饶市| 道孚县| 闵行区| 萝北县| 育儿| 永春县| 赞皇县| 慈溪市| 清河县| 铜山县| 宿州市| 八宿县| 车致| 七台河市| 双江| 赣州市| 饶河县| 双桥区| 老河口市| 沙坪坝区| 科技| 永善县|