python的另一個內建函數 reduce() ,概念上比 filter()map() 複雜一點點。



Introduction

有別於 map()filter() 的重心都在轉換list, reduce() 是將 list 匯整成一個物件。

reduce(function, sequence, initial_value) 會依序先取出兩個 list 中的元素,套入 function 作用後,再將 function 的回傳值再與 List 中的下一個元素一同作為參數傳入f unction,以此類推,直到 list 裡的所有元素都被取完。也因此,傳入 reduce() 中的 function 必須是具有兩個參數的函式。

1
2
3
4
5
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def fn(x, y):
return x+y
reduce(fn, a) # 45

當然, lambda 也可以用進來:

1
2
3
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
reduce(lambda x, y: x+y, a) # 45

簡單的圖解來說明一下 reduce() 對list a 做了什麼事:

reduce() 還可以傳入第三個參數作為起始值:

1
reduce(lambda x, y: x + y, a, 10) # 55

如果沒有特別給定起始值,預設是list的第一個元素為起始值。

Implementation

1
2
3
4
5
6
7
def myreduce(fnc, seq):
val = seq[0]
for item in seq[1:]:
val = fnc(val, item)
return val
myreduce(lambda x, y: x * y, [1,2,3,4]) # 24

More about reduce()

除了數字組成的 list,來看看 reduce() 怎麼 reduce 字串:

1
2
L = ['Testing ', 'shows ', 'the ', 'presence', ', ','not ', 'the ', 'absence ', 'of ', 'bugs']
reduce(lambda x, y: x + y, L) # 'Testing shows the presence, not the absence of bugs'

join() 也可以達到一樣的結果

1
''.join(L) # 'Testing shows the presence, not the absence of bugs'

同場加映,用另一個方法:operator

1
2
import operator
reduce(operator.add, L) # 'Testing shows the presence, not the absence of bugs'

參考連結:
http://fcamel-fc.blogspot.tw/2011/08/python-1.html
http://www.bogotobogo.com/python/python_fncs_map_filter_reduce.php