日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python-functools (reduce,偏函数partial,lru_cache)

發布時間:2025/3/20 python 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python-functools (reduce,偏函数partial,lru_cache) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、functools模塊—reduce()

reduce方法:

reduce方法,就是減少

可迭代對象不能為空,初始值沒提供就在可迭代對象總去一個元素。

def reduce(function, iterable, initializer=None):it = iter(iterable)if initializer is None:value = next(it)else:value = initializerfor element in it:value = function(value, element)return valuereduce()實現代碼

舉例1:

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' from functools import reduce # reduce() print(reduce(lambda a,x:a + x , range(4))) # 6 print(reduce(lambda a,x:a + x , range(4), 10)) # 16num_l=[1,2,3,100] print(reduce(lambda x,y:x+y,num_l,1)) #可以定義起始值,否則默認起始值為第一個元素 print(reduce(lambda x,y:x+y,num_l)) print(reduce(lambda a,x:a + x , [])) # 報錯,根據定義看,如果沒有初始值,那會去迭代對象取第一個值,但是為空,無法next(it)

2、functools ----partial 方法

偏函數:把函數部分的參數固定下來,相當于為部分的參數添加了一個固定的默認值,形成一個新的函數并返回

從 partial 生成的新函數,是對原函數的封裝—裝飾器

def partial(func, *args, **keywords):def newfunc(*fargs, **fkeywords):newkeywords = keywords.copy()newkeywords.update(fkeywords)return func(*args, *fargs, **newkeywords)newfunc.func = funcnewfunc.args = argsnewfunc.keywords = keywordsreturn newfunc

舉例 1:

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def partial(func, *args, **keywords):def newfunc(*fargs, **fkeywords):newkeywords = keywords.copy()newkeywords.update(fkeywords)return func(*args, *fargs, **newkeywords)''' 這是什么意思?'''# newfunc.func = func# print(newfunc.func) # <function add at 0x00000000029DCF28># newfunc.args = args# print(newfunc.args) # ()# newfunc.keywords = keywords# print(newfunc.keywords) # {'y': 5}return newfuncdef add(x, y):return x + y newadd = partial(add,y=5) # print(newadd(4))

舉例2:

from functools import partial import inspectdef add(x:int, y):return x + ynewadd = partial(add, 4) print(inspect.signature(newadd)) print(newadd(5))# (y) # 9newadd = partial(add, y=5) print(inspect.signature(newadd)) print(newadd(4))# (x, *, y=5) # 因為 y=5 是關鍵字傳參,還是可以被更新,所以還是會出現的 # 9newadd = partial(add, x=4,y=5) print(inspect.signature(newadd)) print(newadd())# (*, x=4, y=5) # 9newadd = partial(add,x=4,y=5) print(inspect.signature(newadd)) print(newadd(x=10,y=12))# (*, x=4, y=5) # 22# newadd = partial(add, x=5) # 報錯,雖然x=5被**kwargs收了,但是 4 傳入后是frags,最終賦給x,而后面有x=5,重復 # print(newadd(4))

舉例3:針對 from functools import wraps 的分析

'''偏函數作用:把一些函數從多參---變成單參----這些函數就可以當無參裝飾器''' ''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' def update_wrapper(wrapper, wrapped, assigned = WRAPPER_ASSIGNMENTS,updated = WRAPPER_UPDATES):def wraps(wrapped, @wraps(fn) 等價 w=wraps(fn)(w) 而wraps(fn)就是一個新函數 assigned = WRAPPER_ASSIGNMENTS, wraps函數中可以看到,傳入 w,其他的都是固定值,同時返回一個偏函數updated = WRAPPER_UPDATES): 偏函數只有第一個參數沒有定,假設生成一個新函數 new()return partial(update_wrapper, wrapped=wrapped,assigned=assigned, updated=updated) 這個new() 只需傳入 update_wrapper參數即可,當傳入后,update_wrapper只剩wrapped這個參數, w=wraps(fn)(w)這個第二個參數就是wfrom functools import update_wrapper,wrapsdef logger(fn):@wraps(fn) # w=wraps(fn)(w)結構就是一個柯里化的樣式def w(*args, **kwargs):''' this is wrapper function'''print('執行業務功能之前')ret = fn(*args, **kwargs)print('執行業務功能之后')return ret# update_wrapper(w, fn)return w@logger # add = logger(add) ----> add = wrapper def add(x, y):''' this is add function''' # 這個只能放在第一行才能打印!!!!!return x + y

3、lru_cache

functools.lru_cache(maxsize=128, typed=False)

Least-recently-used 裝飾器,lru 最近最少使用。cache緩存
如果maxsize 設置為 None,則禁用LRU 功能,并且緩存可以無限制增長,當maxsize是二的冪次時,LRU 功能執行的最好
如果typed設置為True,則不同類型的函數將單獨緩存,例如 f(3) 和 f(3.0)將被視為具有不同結果的不同調用。

舉例 1:

from functools import lru_cache import time@lru_cache() # 帶參的裝飾器 def add(x=[], y=1):x.append(y)return xprint(add()) print(add()) # 第二次執行,是直接找上次的結果,并不會在追加,如果不加緩存,就會繼續追加print(add([0])) # 不可hash,以為@lru_cache 原碼影響。

lru_cache 源碼分析:

''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' class _HashedSeq(list):""" This class guarantees that hash() will be called no more than onceper element. This is important because the lru_cache() will hashthe key multiple times on a cache miss."""__slots__ = 'hashvalue'def __init__(self, tup, hash=hash):self[:] = tupself.hashvalue = hash(tup)def __hash__(self):return self.hashvaluedef _make_key(args, kwds, typed,kwd_mark = (object(),),fasttypes = {int, str, frozenset, type(None)},tuple=tuple, type=type, len=len):"""Make a cache key from optionally typed positional and keyword argumentsThe key is constructed in a way that is flat as possible rather thanas a nested structure that would take more memory.If there is only a single argument and its data type is known to cacheits hash value, then that argument is returned without a wrapper. Thissaves space and improves lookup speed."""# All of code below relies on kwds preserving the order input by the user.# Formerly, we sorted() the kwds before looping. The new way is *much*# faster; however, it means that f(x=1, y=2) will now be treated as a# distinct call from f(y=2, x=1) which will be cached separately.key = argsif kwds:key += kwd_markfor item in kwds.items():key += itemif typed:key += tuple(type(v) for v in args)if kwds:key += tuple(type(v) for v in kwds.values())elif len(key) == 1 and type(key[0]) in fasttypes:return key[0]return _HashedSeq(key)def lru_cache(maxsize=128, typed=False):# 從原碼可以看出,args 只能是元組,因為最終返回 _HashedSeq(key),而事實上,class _HashedSeq(list): 是元組繼承而來,def __init__(self, tup, hash=hash): # 而且必須可hash,所以list,set,dict都不能, # 對傳入的參數,位置參數賦值給key,之后會添加一個 object() 形成一個新的 tuple,再將關鍵字參數,形成的字典,以元組形式與之前的 # 的元組相加,形成新的元組,最后加一個type 即元素的類型。 # 如下: # from functools import _make_key # key = _make_key((1,2,3),{'a':1},False) # print(key) # [1, 2, 3, <object object at 0x000000000019E160>, 'a', 1] # # print(hash(key)) # -147545184494388729

舉例 2:

from functools import lru_cache import time@lru_cache() def add(x=4, y=5):time.sleep(3)return x + yprint(1,add(4,5)) print(2,add(4)) print(3,add(y=5)) print(4,add(x=4,y=5)) print(5,add(y=5,x=4)) print(6,add(4.0,5)) # 如上,每個都要算 3 秒@lru_cache() def add(x=[], y=5):time.sleep(3)x.append(1)return xprint(add([1])) # TypeError: unhashable type: 'list'

總結:lru_cache裝飾器應用

使用前提:
同樣的函數參數一定得到同樣的結果
函數執行時間很長,且要多次執行
本質:函數調用的參數 ==> 返回值
缺點:
不支持緩存過期,key無法過期,shixiao
不支持清除操作
不支持分布式,是一個單機緩存
適用場景:單機上需要空間換時間的地方,可以用緩存來將計算編程快速查詢

總結

以上是生活随笔為你收集整理的Python-functools (reduce,偏函数partial,lru_cache)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。