Python高阶函数

一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

一、map、reduce

map是内置函数,reduce不是。。。

map()

语法: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()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个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()

语法:reduce(func,list)
原理:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

# str转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()的作用是从一个序列中筛出符合条件的元素。由于filter()使用了惰性计算,所以只有在取filter()结果的时候,才会真正筛选并每次返回下一个筛出的元素。

# 把一个序列中的空字符串删掉,可以这么写:

def not_empty(s):
    return s and s.strip()

list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))
# 结果: ['A', 'B', 'C']

三、sorted()

sorted()也是一个高阶函数。用sorted()排序的关键在于实现一个映射函数。
语法:sorted(list, key=func, , reverse=True/false)

# 默认排序
>>> 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']

四、返回函数(闭包)

python不仅可以将函数作为另一个函数的参数,也可以调用一个函数,返回另一个函数。称为闭包

def createCounter():
    n = [0]
    def counter():
        while True:
            n[0] = n[0]+1
            return n[0]
    return counter
# 测试:
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('测试闭包通过!')
else:
    print('测试闭包失败!')    

闭包初始理解有难度,目前理解为:(可能有误)
counterA = createCounter()此步骤可理解为:createCounter()函数创建了list n=[0],并将counter()函数赋值给counterA。每次执行counterA()方法时,会通过counter()改变n(闭包外部变量)的值。
此时再调用counterB = createCounter(),会重新创建list n=[0],并重新创建方法counter()赋值给counterB

五、匿名函数(lambda)

>>> f = lambda x: x * x
>>> f
 at 0x101c6ef28>
>>> f(5)
25

六、装饰器(lambda)

在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

不带参数的装饰器

# 声明装饰器
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')
# 执行结果如下:
>>> now()
call now():
2015-3-25

把@log放到now()函数的定义处,相当于执行了语句:now = log(now)

不带参数的装饰器

# 声明装饰器
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')
# 执行结果如下:
>>> now()
execute now():
2015-3-25

和两层嵌套的decorator相比,3层嵌套的效果是这样的: now = log('execute')(now)
@functools.wraps(func)
def wrapper(*args, **kw): 的作用是将func的属性(比如:name)赋给wrapper

七、偏函数

functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
例如
int(str, base=10)此方法默认的进制是10进制,而我们要使用2进制

>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85

最后,创建偏函数时,实际上可以接收函数对象、args和*kw这3个参数

你可能感兴趣的:(Python高阶函数)