亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在python中緩存函數的最后k個結果

在python中緩存函數的最后k個結果

慕少森 2021-09-11 15:55:28
我想編寫一個函數,它接受一個單參數函數 f 和一個整數 k,并返回一個行為與 f 相同的函數,除了它緩存 f 的最后 k 個結果。例如,如果 memoize 是我們所追求的函數,并且讓 mem_f = memoize(f, 2),那么:    mem_f(arg1) -> f(arg1) is computed and cached      mem_f(arg1) -> f(arg1) is returned from cache      mem_f(arg2) -> f(arg2) is computed and cached      mem_f(arg3) -> f(arg3) is computed and cached, and f(arg1) is evicted我所做的是:def memoize(f,k):    cache = dict()    def mem_f(*args):        if args in cache:            return cache[args]        result = f(*args)        cache[args]= result        return result     return mem_f該函數從緩存中返回結果,如果它不在緩存中,則計算并緩存它。但是,我不清楚如何只緩存 f 的最后 k 個結果?我是新手,任何幫助將不勝感激。
查看完整描述

3 回答

?
浮云間

TA貢獻1829條經驗 獲得超4個贊

你可以functools.lru_cache用來做緩存。我接受一個maxsize參數來控制它緩存的數量:


from functools import lru_cache


@lru_cache(maxsize=2)

def test(n):

    print("calling function")

    return n * 2


print(test(2))

print(test(2))

print(test(3))

print(test(3))

print(test(4))

print(test(4))

print(test(2))

結果:


調用函數

4

4

調用函數

6

6

調用函數

8

8

調用函數

4


查看完整回答
反對 回復 2021-09-11
?
蕭十郎

TA貢獻1815條經驗 獲得超13個贊

解決方案

您可以使用以下方法修復您擁有的代碼OrderedDict:


from collections import OrderedDict


def memoize(f, k):

    cache = OrderedDict()


    def mem_f(*args):

        if args in cache:

            return cache[args]

        result = f(*args)

        if len(cache) >= k:

            cache.popitem(last=False)

        cache[args]= result

        return result 

    return mem_f,cache

測試一下

def mysum(a, b):

    return a + b


mysum_cached,cache = memoize(mysum, 10)

for i in range(100)

    mysum_cached(i, i)


print(cache)

輸出:


OrderedDict([((90, 90), 180), ((91, 91), 182), ((92, 92), 184), ((93, 93), 186), ((94, 94), 188), ((95, 95), 190), ((96, 96), 192), ((97, 97), 194), ((98, 98), 196), ((99, 99), 198)])

此版本memoize可能適用于您自己的代碼。但是,對于生產代碼(即其他人必須依賴的代碼),您可能應該使用functools.lru_cacheMark Meyer 建議的標準庫函數 ( )。


查看完整回答
反對 回復 2021-09-11
?
一只名叫tom的貓

TA貢獻1906條經驗 獲得超3個贊

擴展 Mark Meyer 的絕妙建議,以下是解決方案的使用方式lru_cache和問題的術語:


from functools import lru_cache



def memoize(f, k):

    mem_f = lru_cache(maxsize=k)(f)

    return mem_f



def multiply(a, b):

    print("Called with {}, {}".format(a, b))

    return a * b



def main():

    memo_multiply = memoize(multiply, 2)

    print("Answer: {}".format(memo_multiply(3, 4)))

    print("Answer: {}".format(memo_multiply(3, 4)))

    print("Answer: {}".format(memo_multiply(3, 7)))

    print("Answer: {}".format(memo_multiply(3, 8)))



if __name__ == "__main__":

    main()

結果:


Called with 3, 4

Answer: 12

Answer: 12

Called with 3, 7

Answer: 21

Called with 3, 8

Answer: 24


查看完整回答
反對 回復 2021-09-11
  • 3 回答
  • 0 關注
  • 257 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號