一個(gè)函數(shù)就可以接收另一個(gè)函數(shù)作為參數(shù)凯沪,這種函數(shù)就稱(chēng)之為高階函數(shù)第焰。
一、map著洼、reduce
map是內(nèi)置函數(shù)樟遣,reduce不是。身笤。豹悬。
map()
語(yǔ)法:map(func,list)
原理:map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])=[f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8), f(9) ]
map()傳入的第一個(gè)參數(shù)是f,即函數(shù)對(duì)象本身液荸。由于結(jié)果r是一個(gè)Iterator瞻佛,Iterator是惰性序列,因此通過(guò)list()函數(shù)讓它把整個(gè)序列都計(jì)算出來(lái)并返回一個(gè)list娇钱。
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce()
語(yǔ)法:reduce(func,list)
原理:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
# str轉(zhuǎn)int
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
...
>>> def char2num(s):
... digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
... return digits[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579
二伤柄、filter
filter()的作用是從一個(gè)序列中篩出符合條件的元素。由于filter()使用了惰性計(jì)算文搂,所以只有在取filter()結(jié)果的時(shí)候适刀,才會(huì)真正篩選并每次返回下一個(gè)篩出的元素。
# 把一個(gè)序列中的空字符串刪掉煤蹭,可以這么寫(xiě):
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
# 結(jié)果: ['A', 'B', 'C']
三笔喉、sorted()
sorted()也是一個(gè)高階函數(shù)取视。用sorted()排序的關(guān)鍵在于實(shí)現(xiàn)一個(gè)映射函數(shù)。
語(yǔ)法:sorted(list, key=func, , reverse=True/false)
# 默認(rèn)排序
>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
# 指定排序方式 key
sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
# 倒序 reverse
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
四常挚、返回函數(shù)(閉包)
python不僅可以將函數(shù)作為另一個(gè)函數(shù)的參數(shù)作谭,也可以調(diào)用一個(gè)函數(shù),返回另一個(gè)函數(shù)奄毡。稱(chēng)為閉包
def createCounter():
n = [0]
def counter():
while True:
n[0] = n[0]+1
return n[0]
return counter
# 測(cè)試:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
print('測(cè)試閉包通過(guò)!')
else:
print('測(cè)試閉包失敗!')
閉包初始理解有難度折欠,目前理解為:(可能有誤)
counterA = createCounter()此步驟可理解為:createCounter()函數(shù)創(chuàng)建了list n=[0],并將counter()函數(shù)賦值給counterA。每次執(zhí)行counterA()方法時(shí)吼过,會(huì)通過(guò)counter()改變n(閉包外部變量)的值锐秦。
此時(shí)再調(diào)用counterB = createCounter(),會(huì)重新創(chuàng)建list n=[0]那先,并重新創(chuàng)建方法counter()賦值給counterB
五农猬、匿名函數(shù)(lambda)
>>> f = lambda x: x * x
>>> f
<function <lambda> at 0x101c6ef28>
>>> f(5)
25
六、裝飾器(lambda)
在函數(shù)調(diào)用前后自動(dòng)打印日志售淡,但又不希望修改函數(shù)的定義,這種在代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式慷垮,稱(chēng)之為“裝飾器”(Decorator)揖闸。
不帶參數(shù)的裝飾器
# 聲明裝飾器
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
# 使用裝飾器
@log
def now():
print('2015-3-25')
# 執(zhí)行結(jié)果如下:
>>> now()
call now():
2015-3-25
把@log放到now()函數(shù)的定義處,相當(dāng)于執(zhí)行了語(yǔ)句:now = log(now)
不帶參數(shù)的裝飾器
# 聲明裝飾器
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
# 使用裝飾器
@log('execute')
def now():
print('2015-3-25')
# 執(zhí)行結(jié)果如下:
>>> now()
execute now():
2015-3-25
和兩層嵌套的decorator相比料身,3層嵌套的效果是這樣的: now = log('execute')(now)
@functools.wraps(func)
def wrapper(*args, **kw): 的作用是將func的屬性(比如:name)賦給wrapper
七汤纸、偏函數(shù)
functools.partial的作用就是,把一個(gè)函數(shù)的某些參數(shù)給固定浊垩(也就是設(shè)置默認(rèn)值)贮泞,返回一個(gè)新的函數(shù),調(diào)用這個(gè)新函數(shù)會(huì)更簡(jiǎn)單幔烛。
例如
int(str, base=10)此方法默認(rèn)的進(jìn)制是10進(jìn)制啃擦,而我們要使用2進(jìn)制
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85
最后,創(chuàng)建偏函數(shù)時(shí)饿悬,實(shí)際上可以接收函數(shù)對(duì)象令蛉、args和*kw這3個(gè)參數(shù)