定義
函數式編程是一種編程范式,將電腦運算視為函數的計算
特點
使用
# 將函數作為參數
import math
def add(x, y, f):
return f(x) + f(y)
print(add(-1, 9, abs)) # ==> 10
print(add(4, 16, math.sqrt)) # ==> 6.0
'''map()函數 接收一個函數f和一個list,並依次把函數f作用在list的每個元素上,同時返回一個迭代器,可以依次迭代得到原來list元素處理後的結果 '''
def formatter(x):
return x[0].upper() + x[1:].lower()
for item in map(formatter, ['john', 'TIMY', 'DaniEl']):
print(item) # ⇒ John Timy Daniel
'''reduce()函數 接收一個函數f和一個list,對list的每個元素反復調用函數f,並返回最終結果,可以接收第三個參數作為初始值 Python2中可以直接使用,Python3中需要在functools包中引入 '''
from functools import reduce
def f(x, y):
return x * y
print(reduce(f, [1, 3, 5, 7, 9])) # ⇒ 945
'''filter()函數 接收一個函數f和一個list,通過函數f對每個元素進行判斷,返回True或False,filter()根據判斷結果自動過濾掉不符合條件的元素並返回一個迭代器,可以迭代出所有符合條件的元素 '''
import math
def is_integer(x):
r = int(math.sqrt(x))
return math.pow(r, 2) == x
for item in filter(is_integer, range(1,101)):
print(item) # ⇒ 1 4 9 16 25 36 49 64 81 100
'''sorted()函數 默認從小到大進行排序,當list每一個元素是容器時,則會以第一個元素來排序,返回一個新的list 如果需要指定排序的字段,key參數值是一個函數,接收待排序列表的元素作為參數並返回對應需要排列的字段 如果需要倒序,則需要指定reverse參數為True '''
def k(item):
return item.lower()
name = ['boom', 'about', 'Dog', 'Large']
print(name) # ⇒ ['boom', 'about', 'Dog', 'Large']
newName = sorted(name, key=k)
print(newName) # ⇒ ['about', 'boom', 'Dog', 'Large']
'''返回函數 在函數內部可以定義子函數,同時可以把子函數返回 返回函數時不能帶括號,返回函數值時則需要 '''
from functools import reduce
def f(x, y):
return x * y
def calc_prod(list_):
def prod():
return reduce(f, list_, 1)
return prod
p = calc_prod([1,2,3,4,5])
print(p()) # ⇒ 120
'''閉包 內層函數引用了外層函數的變量,並返回內層函數的結果 注意:返回函數不要引用任何循環變量或者後續會發生變化的變量 '''
def count():
fs = []
for i in range(1, 4):
def f(j):
def g():
return j * j
return g
k = f(i)
fs.append(k)
return fs
f1, f2, f3 = count()
print(f1(), f2(), f3()) # ⇒ (1, 4, 9)
'''匿名函數 匿名函數使用lambda關鍵字進行定義,lambda x,y: x + y,就可以完成函數的定義,冒號前表示匿名函數的參數,冒號後則是一個表達式,不用寫return,返回值就是該表達式的結果 '''
name = ['boom', 'about', 'Large', 'Dog']
print(sorted(name, key=lambda x:x.lower())) # ⇒ ['about', 'boom', 'Dog', 'Large']
''''無參數的decorator 本質上是一個高階函數,接收一個函數作為參數,返回一個新函數 使用@語法,可以避免手動編寫代碼 '''
# 只含一個參數
def log(f):
def fn(x):
print('call ' + f.__name__ + '()...')
return f(x)
return fn
# 含有任意個參數
def log(f):
def fn(*args, **kwargs):
print('call ' + f.__name__ + '()...')
return f(*args, **kwargs)
return fn
# 輸出函數運行時間
import time
def performance(f):
def fn(*args, **kwargs):
t1 = time.time()
r = f(*args, **kwargs)
t2 = time.time()
print('call %s() in %fs' % (f.__name__, (t2-t1)))
return r
return fn
@performance
def add(x, y):
return x + y
add(1, 2) # ⇒ call add() in 0.000003s 3
@performance
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
factorial(10) # ⇒ call factorial() in 0.004084s
'''有參數的decorator 帶參數的decorator首先返回一個decorator函數,再讓這個decorator函數接收一個函數並返回新函數,相當於是在原有的二層函數裡面,增加了一層嵌套 '''
import time
def performance(param):
def performance_decorator(f):
def fn(*args, **kwargs):
t1 = time.time()
r = f(*args, **kwargs)
t2 = time.time()
if param == 's':
print('call %s() in %fs' % (f.__name__, (t2-t1)))
if param == 'ms':
print('call %s() in %fms' % (f.__name__, (t2-t1)*1000))
return r
return fn
return performance_decorator
@performance('ms')
def factorial(n):
return reduce(lambda x,y: x*y, range(1, n+1))
factorial(10) # ⇒ call factorial() in 3.329039ms call factorial() in 0.003894s
'''偏函數 創建一個調用另外一個部分參數或變量已經預置的函數 partial可以將參數多的函數變成參數少的新函數,缺的參數需要指定默認值 '''
from functools import partial
sorted_ignore_case = partial(sorted, key=lambda x: x.lower())
print(sorted_ignore_case(['boom', 'about', 'Large', 'Dog'])) # ⇒ ['about', 'boom', 'Dog', 'Large']