python中的reduce內(nèi)建函數(shù)使用方法指南
官方解釋:
Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). The left argument, x, is the accumulated value and the right argument, y, is the update value from the iterable. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned. Roughly equivalent to:
意思就是說(shuō):將一個(gè)可迭代的對(duì)象應(yīng)用到一個(gè)帶有兩個(gè)參數(shù)的方法上,我們稱之為appFun,遍歷這個(gè)可迭代對(duì)象,將其中的元素依次作為appFun的參數(shù),但這個(gè)函數(shù)有兩個(gè)參數(shù),作為哪個(gè)參數(shù)呢?有這樣的規(guī)則,看一下下面reduce方法的實(shí)現(xiàn),有三個(gè)參數(shù),第一個(gè)參數(shù)就是上面說(shuō)的appFun,第二個(gè)參數(shù)就是那個(gè)可迭代的對(duì)象,而第三個(gè)呢?當(dāng)調(diào)用reduce方法的時(shí)候給出了initializer這個(gè)參數(shù),那么第一次調(diào)用appFun的時(shí)候這個(gè)參數(shù)值就作為第一個(gè)參數(shù),而可迭代對(duì)象的元素依次作為appFun的第二個(gè)參數(shù);如果調(diào)用reduce的時(shí)候沒(méi)有給出initializer這個(gè)參數(shù),那么第一次調(diào)用appFun的時(shí)候,可迭代對(duì)象的第一個(gè)元素就作為appFun的第一個(gè)元素,而可迭代器的從第二個(gè)元素到最后依次作為appFun的第二個(gè)參數(shù),除第一次調(diào)用之外,appFun的第一個(gè)參數(shù)就是appFun的返回值了。例如reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]),計(jì)算1到5的和,因?yàn)闆](méi)有給定initializer參數(shù),所以第一次調(diào)用x+y時(shí),x=1,即列表的第一個(gè)元素,y=2,即列表的第二個(gè)元素,之后返回的1+2的結(jié)果作為第二次調(diào)用x+y中的x,即上一次的結(jié)果,y=2,即第二個(gè)元素,依次類推,知道得到1+2+3+4+5的結(jié)果。
這樣看來(lái),其實(shí)下面的代碼定義是有一點(diǎn)問(wèn)題,我們?cè)诔绦蛑姓{(diào)用這段代碼reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]),得到的結(jié)果為16,而正確的結(jié)果為15,問(wèn)題在于如果集合不是以0開始,那么按照如下代碼,第一次調(diào)用x=1,即第一個(gè)元素,y也是等于1,也是第一個(gè)元素,而正確的y應(yīng)該是2。所以真正的reduce方法應(yīng)該和下面的例子是有差別的。
def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
try:
initializer = next(it)
except StopIteration:
raise TypeError('reduce() of empty sequence with no initial value')
accum_value = initializer
for x in iterable:
accum_value = function(accum_value, x)
return accum_value
那么reduce函數(shù)能做什么,什么情況下要用reduce呢,看下面的例子:
例如上面的例子,實(shí)現(xiàn)一個(gè)整形集合的累加。假設(shè)lst = [1,2,3,4,5],實(shí)現(xiàn)累加的方式有很多:
第一種:用sum函數(shù)。
sum(lst)
第二種:循環(huán)方式。
def customer_sum(lst):
result = 0
for x in lst:
result+=x
return result
#或者
def customer_sum(lst):
result = 0
while lst:
temp = lst.pop(0)
result+=temp
return result
if __name__=="__main__":
lst = [1,2,3,4,5]
print customer_sum(lst)
第三種:遞推求和
def add(lst,result):
if lst:
temp = lst.pop(0)
temp+=result
return add(lst,temp)
else:
return result
if __name__=="__main__":
lst = [1,2,3,4,5]
print add(lst,0)
第四種:reduce方式
lst = [1,2,3,4,5] print reduce(lambda x,y:x+y,lst) #這種方式用lambda表示當(dāng)做參數(shù),因?yàn)闆](méi)有提供reduce的第三個(gè)參數(shù),所以第一次執(zhí)行時(shí)x=1,y=2,第二次x=1+2,y=3,即列表的第三個(gè)元素 #或者 lst = [1,2,3,4,5] print reduce(lambda x,y:x+y,lst,0) #這種方式用lambda表示當(dāng)做參數(shù),因?yàn)橹付藃educe的第三個(gè)參數(shù)為0,所以第一次執(zhí)行時(shí)x=0,y=1,第二次x=0+1,y=2,即列表的第二個(gè)元素, 假定指定reduce的第三個(gè)參數(shù)為100,那么第一次執(zhí)行x=100,y仍然是遍歷列表的元素,最后得到的結(jié)果為115 #或者 def add(x,y): return x+y print reduce(add, lst) #與方式1相同,只不過(guò)把lambda表達(dá)式換成了自定義函數(shù) #或者 def add(x,y): return x+y print reduce(add, lst,0) #與方式2相同,只不過(guò)把lambda表達(dá)式換成了自定義函數(shù)
再舉一個(gè)例子:有一個(gè)序列集合,例如[1,1,2,3,2,3,3,5,6,7,7,6,5,5,5],統(tǒng)計(jì)這個(gè)集合所有鍵的重復(fù)個(gè)數(shù),例如1出現(xiàn)了兩次,2出現(xiàn)了兩次等。大致的思路就是用字典存儲(chǔ),元素就是字典的key,出現(xiàn)的次數(shù)就是字典的value。方法依然很多
第一種:for循環(huán)判斷
def statistics(lst):
dic = {}
for k in lst:
if not k in dic:
dic[k] = 1
else:
dic[k] +=1
return dic
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5]
print(statistics(lst))
第二種:比較取巧的,先把列表用set方式去重,然后用列表的count方法
def statistics2(lst):
m = set(lst)
dic = {}
for x in m:
dic[x] = lst.count(x)
return dic
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5]
print statistics2(lst)
第三種:用reduce方式
def statistics(dic,k):
if not k in dic:
dic[k] = 1
else:
dic[k] +=1
return dic
lst = [1,1,2,3,2,3,3,5,6,7,7,6,5,5,5]
print reduce(statistics,lst,{})
#提供第三個(gè)參數(shù),第一次,初始字典為空,作為statistics的第一個(gè)參數(shù),然后遍歷lst,作為第二個(gè)參數(shù),然后將返回的字典集合作為下一次的第一個(gè)參數(shù)
或者
d = {}
d.extend(lst)
print reduce(statistics,d)
#不提供第三個(gè)參數(shù),但是要在保證集合的第一個(gè)元素是一個(gè)字典對(duì)象,作為statistics的第一個(gè)參數(shù),遍歷集合依次作為第二個(gè)參數(shù)
通過(guò)上面的例子發(fā)現(xiàn),凡是要對(duì)一個(gè)集合進(jìn)行操作的,并且要有一個(gè)統(tǒng)計(jì)結(jié)果的,能夠用循環(huán)或者遞歸方式解決的問(wèn)題,一般情況下都可以用reduce方式實(shí)現(xiàn)。
reduce函數(shù)真是“一位好同志啊”!
相關(guān)文章
Python os模塊中的isfile()和isdir()函數(shù)均返回false問(wèn)題解決方法
這篇文章主要介紹了Python os模塊中的isfile()和isdir()函數(shù)均返回false問(wèn)題解決方法,返回false的原因是路徑使用了相對(duì)路徑,使用絕對(duì)路徑就可以解決這個(gè)問(wèn)題,需要的朋友可以參考下2015-02-02
Python開發(fā)工具PyCharm的下載與安裝步驟圖文教程
這篇文章主要為大家介紹了Python開發(fā)工具PyCharm的下載與安裝步驟圖文教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
django-rest-swagger對(duì)API接口注釋的方法
今天小編就為大家分享一篇django-rest-swagger對(duì)API接口注釋的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08
Python數(shù)據(jù)結(jié)構(gòu)之遞歸可視化詳解
遞歸函數(shù)是直接調(diào)用自己或通過(guò)一系列語(yǔ)句間接調(diào)用自己的函數(shù)。遞歸在程序設(shè)計(jì)有著舉足輕重的作用,在很多情況下,借助遞歸可以優(yōu)雅的解決問(wèn)題。本文主要介紹了如何利用可視化方式來(lái)了解遞歸函數(shù)的執(zhí)行步驟,需要的可以參考一下2022-04-04
用Django實(shí)現(xiàn)一個(gè)可運(yùn)行的區(qū)塊鏈應(yīng)用
這篇文章主要介紹了用Django實(shí)現(xiàn)一個(gè)可運(yùn)行的區(qū)塊鏈應(yīng)用,需要的朋友可以參考下2018-03-03
tensorflow 1.X遷移至tensorflow2 的代碼寫法
本文主要介紹了tensorflow 1.X遷移至tensorflow2 的代碼寫法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
python 默認(rèn)參數(shù)問(wèn)題的陷阱
本文給大家講述的是python 默認(rèn)參數(shù)問(wèn)題的陷阱,有需要的小伙伴可以參考下2016-02-02
如何利用python獲取鼠標(biāo)點(diǎn)擊的實(shí)時(shí)位置案例
這篇文章主要給大家介紹了關(guān)于如何利用python獲取鼠標(biāo)點(diǎn)擊的實(shí)時(shí)位置,并展示了如何安裝和使用該庫(kù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-12-12

