Preface
在 Python 的 __builtin__ 模組 中有一些函式,不需要 import 也可以使用,有幾個簡單好用的資料處理函式值得介紹:
range、zip 與 enumerate
要瞭解這些資料處理函式如何使用,最好的方式就是從練習開始 …
練習 6:使用 range、zip 與 enumerate
在 Python 中,如果想使用 for in 語法來迭代 list,而且希望取得索引資訊,該如何進行呢?例如,如果有個 list = ['Justin', 'caterpillar', 'openhome'],想要有以下的顯示結果:
先給個小提示,程式基本上可以長這樣:
- names = ['Justin', 'caterpillar', 'openhome']
- for ______ in ______:
- print '{0}, {1}'.format(______)
reduce
__builtin__ 模組 中的 reduce,有時在別的語言中會被稱為 foldLeft,它其實代表了一種高度抽象化後的流程重用,只要是打算從清單中求值的需求,基本上都可以使用它。
舉例來說,如果你想要知道 [1, 2, 3, 4, 5] 的加總,雖然可以直接撰寫迴圈來求值,不過,也可以撰寫為 reduce(lambda sum, elem: sum + elem, [1, 2, 3, 4, 5], 0) 來求值,試試在 Python 互動環境中鍵入,結果會是 15。初學者會有點難懂 reduce 的原理,可以藉由這段動畫來理解,你也就會知道,為什麼它又在別的語言中,被稱為 foldLeft:
如果 reduce 接受的 lambda 部份,改為一個具體名稱的 add 函式,那麼就可以寫為 為 reduce(add, [1, 2, 3, 4, 5], 0) ,配合上圖,reduce 的運作就像是折紙,從 0 開始,每折一次就與藍色數字進行一次 add,折完後的結果就是加總值。
練習 7:使用 reduce
使用 reduce 與 for 包含式,將以下的範例進行重構,目標是清除所有顯式的迴圈流程:
- # coding=UTF-8
- def ascending(a, b): return a - b
- def descending(a, b): return -ascending(a, b)
- # selection sort
- def sorted(xs, compare = ascending):
- return [] if not xs else __select(xs, compare)
- def __select(xs, compare):
- selected = xs[0]
- for elem in xs[1:]:
- if compare(elem, selected) < 0:
- selected = elem
- remain = []
- selected_list = []
- for elem in xs:
- if elem != selected:
- remain.append(elem)
- else:
- selected_list.append(elem)
- return xs if not remain else selected_list + __select(remain, compare)
- print sorted([2, 1, 3, 6, 5])
- print sorted([2, 1, 3, 6, 5], descending)
- # coding=UTF-8
- def ascending(a, b): return a - b
- def descending(a, b): return -ascending(a, b)
- # selection sort
- def _sorted(xs, compare = ascending):
- return [] if not xs else __select(xs, compare)
- def _sep(slt, elm, remain, selected_list):
- if elm != slt:
- remain.append(elm)
- else:
- selected_list.append(elm)
- return slt
- def __select(xs, compare):
- selected = xs[0]
- reduce(lambda slt, elm: slt if compare(elm, selected) > 0 else elm, xs[1:], selected)
- remain = []
- selected_list = []
- reduce(_sep, xs, selected)
- return xs if not remain else selected_list + __select(remain, compare)
- print _sorted([2, 1, 3, 6, 5, 2])
- print _sorted([2, 1, 3, 6, 5, 2], descending)
關於函數式程式設計
想要知道 reduce 的原理,可以看看 List 處理模式 中的說明。 實際上,reduce 與 for 包含式的概念源自函數式程式設計(Functional programming),嗯?好像很高深,其實如果你能完成練習 7,你已經做了一次函數式程式設計了。
不過,何時該使用函數式的元素,取決於可讀與風格問題,在 Python 中確實是有那麼一些函數式程式設計的元素,for 包含式在 Python 中應用的很多,因為可以增加可讀性,然而像 reduce 這種元素,由於可讀性並不好,因而並不太鼓勵去用它,用更具體的函式名稱來封裝 reduce 會更好,以上面的加總來說,可以寫個 sum 函式來表達意圖。實際上,在 Python 3 中,reduce 不再位於 __builtin__ 模組,而被移至 funtools 模組了。
無論如何,藉由這個練習,瞭解到 Python 可進行多重典範設計,只要你願意的話,函數式是可以的設計之一;接下來的內容,是要介紹 Python 中對永續化(Persistence)的基本支援,順便來看看幾種永續設計方式 - Python Tutorial 第三堂(3)永續化機制
Supplement
* python內置函數 map/reduce/filter
沒有留言:
張貼留言