官方解釋:
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:
意思就是說:將一個可迭代的對象應用到一個帶有兩個參數(shù)的方法上,我們稱之為appFun,遍歷這個可迭代對象,將其中的元素依次作為appFun的參數(shù),但這個函數(shù)有兩個參數(shù),作為哪個參數(shù)呢?有這樣的規(guī)則,看一下下面reduce方法的實現(xiàn),有三個參數(shù),第一個參數(shù)就是上面說的appFun,第二個參數(shù)就是那個可迭代的對象,而第三個呢?當調用reduce方法的時候給出了initializer這個參數(shù),那么第一次調用appFun的時候這個參數(shù)值就作為第一個參數(shù),而可迭代對象的元素依次作為appFun的第二個參數(shù);如果調用reduce的時候沒有給出initializer這個參數(shù),那么第一次調用appFun的時候,可迭代對象的第一個元素就作為appFun的第一個元素,而可迭代器的從第二個元素到最后依次作為appFun的第二個參數(shù),除第一次調用之外,appFun的第一個參數(shù)就是appFun的返回值了。例如reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]),計算1到5的和,因為沒有給定initializer參數(shù),所以第一次調用x+y時,x=1,即列表的第一個元素,y=2,即列表的第二個元素,之后返回的1+2的結果作為第二次調用x+y中的x,即上一次的結果,y=2,即第二個元素,依次類推,知道得到1+2+3+4+5的結果。
這樣看來,其實下面的代碼定義是有一點問題,我們在程序中調用這段代碼reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]),得到的結果為16,而正確的結果為15,問題在于如果集合不是以0開始,那么按照如下代碼,第一次調用x=1,即第一個元素,y也是等于1,也是第一個元素,而正確的y應該是2。所以真正的reduce方法應該和下面的例子是有差別的。
那么reduce函數(shù)能做什么,什么情況下要用reduce呢,看下面的例子:
例如上面的例子,實現(xiàn)一個整形集合的累加。假設lst = [1,2,3,4,5],實現(xiàn)累加的方式有很多:
第一種:用sum函數(shù)。
第二種:循環(huán)方式。
第三種:遞推求和
第四種:reduce方式
再舉一個例子:有一個序列集合,例如[1,1,2,3,2,3,3,5,6,7,7,6,5,5,5],統(tǒng)計這個集合所有鍵的重復個數(shù),例如1出現(xiàn)了兩次,2出現(xiàn)了兩次等。大致的思路就是用字典存儲,元素就是字典的key,出現(xiàn)的次數(shù)就是字典的value。方法依然很多
第一種:for循環(huán)判斷
第二種:比較取巧的,先把列表用set方式去重,然后用列表的count方法
第三種:用reduce方式
通過上面的例子發(fā)現(xiàn),凡是要對一個集合進行操作的,并且要有一個統(tǒng)計結果的,能夠用循環(huán)或者遞歸方式解決的問題,一般情況下都可以用reduce方式實現(xiàn)。
reduce函數(shù)真是“一位好同志啊”!