來(lái)源:rainyear
鏈接:https://github.com/rainyear/pytips/blob/master/Markdowns/2016-03-08-Functional-Programming-in-Python.md(點(diǎn)擊尾部閱讀原文前往)
函數式編程(英語(yǔ):functional programming)或稱(chēng)函數程序設計,又稱(chēng)泛函編程,是一種編程范型,它將電腦運算視為數學(xué)上的函數計算,并且避免使用程序狀態(tài)以及易變對象。函數編程語(yǔ)言最重要的基礎是λ演算(lambda calculus)。而且λ演算的函數可以接受函數當作輸入(引數)和輸出(傳出值)。(維基百科:函數式編程)
所謂編程范式(Programming paradigm)是指編程風(fēng)格、方法或模式,比如面向過(guò)程編程(C語(yǔ)言)、面向對象編程(C++)、面向函數式編程(Haskell),并不是說(shuō)某種編程語(yǔ)言一定屬于某種范式,例如 Python 就是多范式編程語(yǔ)言。
函數式編程
函數式編程具有以下特點(diǎn):
1、避免狀態(tài)變量
2、函數也是變量(一等公民,First-Class Citizen)
3、高階函數
4、面向問(wèn)題描述而不是面向問(wèn)題解決步驟
值得一提的是,函數式編程的這些特點(diǎn)在實(shí)踐過(guò)程中可能并不是那么 Pythonic,甚至與0×00 (https://github.com/rainyear/pytips/blob/master/Tips/2016-03-06-The-Zen-of-Python.ipynb) 中提到的 The Zen of Python 相悖。例如函數式編程面向問(wèn)題描述的特點(diǎn)可能讓你更快地寫(xiě)出更簡(jiǎn)潔的代碼,但可讀性卻也大打折扣(可參考這一段Haskell代碼 https://gist.github.com/rainyear/94b5d9a865601f075719)。不過(guò),雖然 Pythonic 很重要但并不是唯一的準則,The Choice Is Yours。
map(function, iterable, ...)/filter(function, iterable)
# map 函數的模擬實(shí)現
def myMap(func, iterable):
for arg in iterable:
yield func(arg)
names = ['ana', 'bob', 'dogge']
print(map(lambda x: x.capitalize(), names)) # Python 2.7 中直接返回列表
for name in myMap(lambda x: x.capitalize(), names):
print(name)
Ana
Bob
Dogge
# filter 函數的模擬實(shí)現
def myFilter(func, iterable):
for arg in iterable:
if func(arg):
yield arg
print(filter(lambda x: x % 2 == 0, range(10))) # Python 2.7 中直接返回列表
for i in myFilter(lambda x: x % 2 == 0, range(10)):
print(i)
0
2
4
6
8
functools.reduce(function, iterable[, initializer])
Python 3.5 中reduce 被降格到標準庫functools,reduce 也是遍歷可迭代對象元素作為第一個(gè)函數的參數,并將結果累計:
from functools import reduce
print(reduce(lambda a, b: a*b, range(1,5)))
24
functools.partial(func, *args, **keywords)
偏應用函數(Partial Application)讓我們可以固定函數的某些參數:
from functools import partial
add = lambda a, b: a + b
add1024 = partial(add, 1024)
add1024(1)
1025
這里簡(jiǎn)單介紹了一些常用函數式編程的方法和概念,實(shí)際上要傳達的一個(gè)最重要的觀(guān)念就是函數本身也可以作為變量被返回、傳遞給高階函數,這使得我們可以更靈活地運用函數解決問(wèn)題。但是這并不意味著(zhù)一定要使用上面這些方法來(lái)簡(jiǎn)化代碼,例如更 Pythonic 的方法推薦盡可能使用 List Comprehension 替代map/filter(關(guān)于 List Comprehension 后面會(huì )再單獨介紹)。如果一定想要用函數式編程的方法來(lái)寫(xiě) Python,也可以嘗試Fn.py,或者,試試 Haskell。
參考
1、維基百科:函數式編程
2、byvoid:APIO講稿——函數式編程
●本文編號55,以后想閱讀這篇文章直接輸入55即可。
●輸入m可以獲取到文章目錄
聯(lián)系客服