Wiki上對Functional Programming的定義:html
In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions[1] or declarations[2] instead of statements. In functional code, the output value of a function depends only on the arguments that are input to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) each time.** Eliminating side effects, i.e. changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming. **python
"函數式編程"是一種"編程範式"(programming paradigm),一種構建計算機程序結構和元素的風格/模式。它把運算看成是數據函數的計算,避免了多變的狀態和易變的數據。它是一種聲明性編程範式,意味着程序是由表達式或聲明完成的而不是語句。在函數代碼中,函數的輸出值只依賴於對這個函數的輸入,所以以一樣的參數值x調用函數f兩次,每次獲得的結果是相同的f(x)。消除反作用,即狀態的改變再也不依賴於函數的輸入,這使理解和預測程序的行爲更加容易,這也是發展函數式編程的主要動力。****express
所謂"反作用"(side effect),指的是函數內部與外部互動(最典型的狀況,就是修改全局變量的值),產生運算之外的其餘結果。
函數式編程強調沒有"反作用",意味着函數要保持獨立,全部功能就是返回一個新的值,沒有其餘行爲,尤爲是不得修改外部變量的值。編程
和聲明性編程對應的是命令式編程(imperative programming), 它在源程序中使用命令改變狀態,最簡單的例子就是賦值。存在的反作用是可能改變程序狀態的值。所以函數沒有返回值是有意義的。因爲它們缺乏引用透明性(referential transparency),即根據程序的執行狀態在不一樣的時間,相同的表達式可能會產生不一樣的結果。閉包
引用透明(Referential transparency),指的是函數的運行不依賴於外部變量或"狀態",只依賴於輸入的參數,任什麼時候候只要參數相同,引用函數所獲得的返回值老是相同的。app
函數式編程就是一種抽象程度很高的編程範式,純粹的函數式編程語言編寫的函數沒有變量(應該也存在不是純粹的函數式編程,使用函數式編程解決局部問題,同時也存在變量),所以,任意一個函數,只要輸入是肯定的,輸出就是肯定的,這種純函數咱們稱之爲沒有反作用。而容許使用變量的程序設計語言,因爲函數內部的變量狀態不肯定,一樣的輸入,可能獲得不一樣的輸出,所以,這種函數是有反作用的。編程語言
函數式編程就是如何編寫程序的方法論。
它屬於"結構化編程"的一種,主要思想是把運算過程儘可能寫成一系列嵌套的函數調用。舉例來講,如今有這樣一個數學表達式:ide
(1 + 2) * 3 - 4
傳統的過程式編程,可能這樣寫:函數式編程
var a = 1 + 2; var b = a * 3; var c = b - 4;
函數式編程要求使用函數,咱們能夠把運算過程定義爲不一樣的函數,而後寫成下面這樣:函數
var result = subtract(multiply(add(1,2), 3), 4);
這就是函數式編程。
Python中一切皆爲對象。函數也不例外,且函數與其餘數據類型同樣,處於平等地位。
函數能夠賦值給變量,也能夠做爲參數,傳入另外一個函數,或者做爲別的函數的返回值。函數名其實就是指向函數的變量,它能夠被賦其餘值。
這樣才能快捷實施函數式編程,C語言裏函數與變量不平等的,或許藉助函數指針卻是能夠實現,但頗爲麻煩。
函數賦值給其餘變量
>>> abs(-10) 10 >>> foo = abs >>> foo(-10) 10
函數名被賦其餘變量
>>> abs <built-in function abs> >>> abs = 10 >>> abs 10
函數做爲參數傳遞給另外一函數
>>> def add(x, y, foo): ... return foo(x) + foo(y) ... >>> add(-10, 3, abs) 13
函數做爲返回值返回
>>> def foo(): return abs ... ... >>> fun = foo() >>> fun(-10) 10
lambda表達式用於建立匿名函數,是一種簡化函數定義的快速方法。不像def那樣能夠執行多重語句和註釋,lambda形式定義的函數沒有def形式的強大。優勢是快速簡單,一條語句就可定義一個函數。
lambda語法以下:
lambda arguments: expression
lambda定義一個求和函數add。
add = lambda x, y: x + y
效果和def形式定義的是同樣的。
def add(x, y): return x + y
lambda表達式一般是直接嵌入在須要函數的地方,且該函數能使用一個表達式完整描述,不大會直接將lambda表達式命令成函數。這雖然很酷,可是不方便拓展,若是一開始就須要給函數命名,應該使用def形式定義。
打印斐波那契數列前10個。
def fibonacci(n, first=0, second=1): while n != 0: print(first, end="\n") # side-effect n, first, second = n - 1, second, first + second # assignment fibonacci(10)
fibonacci = (lambda n, first=0, second=1: "" if n == 0 else str(first) + "\n" + fibonacci(n - 1, second, first + second)) print(fibonacci(10), end="")
此處的lambda表達式略微複雜,換成def的形式:
def fibonacci(n, first=0, second=1): if n == 0: return '' else: return str(first) + "\n" + fibonacci(n - 1, second, first + second) print(fibonacci(10), end="")
循環是在描述咱們該如何地去解決問題。
遞歸是在描述這個問題的定義。
簡單點理解,函數式編程就是把函數當普通的變量或對象同樣使用,函數用作參數或返回值。函數自身帶有邏輯計算,當變量使用能夠獲得很是高效的代碼。
傳統的說,Python是一種非函數式語言(non-functional),但在編碼時可使用函數式風格。Python中的lambda,高階函數(map, reduce, filter),偏函數(partial function),閉包(closure),裝飾器(decorator)都有函數式思想。經過 Python 中的高階函數稍稍體會下函數式編程的趣味。
把函數做爲參數傳入的函數,這樣的函數稱爲高階函數。Python中知名高階函數有map, reduce, filter。
map
| map(func, *iterables) --> map object
|
| Make an iterator that computes the function using arguments from
| each of the iterables. Stops when the shortest iterable is exhausted.
map()傳入的第一個參數是函數,第二個參數是Iterable
對象,便可迭代的對象,如list,dict,str都是Iterable
對象。map將函數func依次做用到Iterable
對象的元素上,返回一map對象。(map對象是?)
以下將list中元素平方後獲得新的list。
>>> ret= map(lambda x: x*x, list(range(5))) >>> print(ret) <map object at 0x029AE4B0> >>> print(list(ret)) [0, 1, 4, 9, 16]
不是很嚴格的map()實現:
from collections import Iterable def map(func, a_iterable): result = [] if isinstance(a_iterable, Iterable) is False: raise TypeError('%s object is not iterable' % type(a_iterable)) else: for item in a_iterable: result.append(func(item)) return result
reduce
Python3裏 reduce() 在 functools 模塊下。
functools.reduce = reduce(...)
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
reduce()最少接收2個參數,最多接收3個參數,第2個參數要求可迭代的。reduce()做用效果:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
>>> from functools import reduce >>> reduce(lambda x, y: x+y, [1, 2, 3], 10) 16 >>> reduce(lambda x, y: x+y, [1, 2, 3]) 6
map() 和 reduce() 結合使用實現 str 到 int 的過程,簡潔又酷炫。
from functools import reduce def str2int(a_str): char2int = lambda x :{'0':0, '1':1, '2':2, '3':3, '4': 4, '5': 5, '6': 6, '7':7, '8': 8, '9': 9}[x] return reduce(lambda x, y: x*10+y, map(char2int, a_str)) print(str2int('1234'))
filter
class filter(object)
| filter(function or None, iterable) --> filter object
|
| Return an iterator yielding those items of iterable for which function(item)
| is true. If function is None, return the items that are true.
filter()也接收一個函數和一個序列。和 map()不一樣的時,filter()把傳入的函數依次做用於每一個元素, 而後根據返回值是 True 仍是 False 決定保留仍是丟棄該元素。
如獲得序列中的整數:
>>> ret = filter(lambda x: x if x>0 else None, [1, -2, 3, -4, 0]) >>> print(ret) <filter object at 0x029AEEF0> >>> print(list(ret)) [1, 3]
sorted
sorted(iterable, key=None, reverse=False)
Return a new list containing all items from the iterable in ascending order.
|
A custom key function can be supplied to customise the sort order, and the
reverse flag can be set to request the result in descending order.
sorted()函數也是一個高階函數,它還能夠接收一個 key 函數來實現自定義的排序。
按絕對值排序
>>> sorted([1, -2, -3, 4], key=abs) [1, -2, -3, 4]
問題:
有這樣一個 list :['1y','3m','1m','7d','5d','1d','12h','6h','3h']
其中 y 表示年, m 表示月, d 表示天, h 表示小時,前面的數字表示對應的時間
問如何用 sort 在一行內按照年>月>天>小時或者反過來的順序進行排序?
>>> a_list = ['1y','3m','1m','7d','5d','1d','12h','6h','3h'] >>> sorted(a_list, key = lambda x: {'y':365*24, 'm':30*24, 'd':24, 'h':1}[x[-1]] * int(x[:-1])) ['3h', '6h', '12h', '1d', '5d', '7d', '1m', '3m', '1y']
1.wiki-Functional programming
2.Python函數式編程指南(一):概述
3.函數式編程掃盲篇
4.函數式編程初探
5.函數式編程
完---若有錯漏,請指教:)