Python之函数式编程
一、高阶函数
1.map:
用法:map(函数对象,序列)
作用:将序列内每一个对象作用与函数的参数并生成一个新的序列返回
例子:将列表中的名字首字母大写 其余字母小写放入列表中
def OrderName(name): g = lambda Newname:Newname[0].upper() + Newname[1:].lower() return g(name) lst = ['adam', 'LISA', 'barT'] print map(OrderName, lst)
2.reduce:
用法:reduce(函数对象,序列)
作用:reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
例子:Python提供的sum()
函数可以接受一个list并求和,编写一个prod()
函数,可以接受一个list并利用reduce()
求积。
def prod(lst): return reduce(lambda x, y: x*y, lst) lst = [1,2,3,4,5,6] print prod(lst)
3.filter
用法:filter(函数对象,序列)
作用:filter()
把传入的函数依次作用于每个元素,然后根据返回值是True(保留)
还是False
决定保留还是丢弃该元素。相当于一个筛选。
例子:使用filter()筛除 1~100 的素数
def mDel(num): if num == 1: return True for i in range(2, num): if num % i == 0: return True return False print filter(mDel, range(1, 101))
## 考虑 1 不是 素数 也不是合数 所以应该保留 1 ##
4.sorted
排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来。通常规定,对于两个元素x
和y
,如果认为x < y
,则返回-1
,如果认为x == y
,则返回0
,如果认为x > y
,则返回1
,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。
也可以在 使用 sorted(序列,自定义比较函数) 来拟定自己的规则进行比较并得出比较结果。
例子:不分大小写比较一组姓名(由于直接比较会导致ASCII码在后的小写字母判断比大写字母值小)
def myCmp(s1, s2): u1 = s1.upper() u2 = s2.upper() if u1 > u2: return 1 elif u1 == u2: return 0 elif u1 < u2: return -1 lst = ['bob', 'about', 'Zoo', 'Credit'] print sorted(lst, myCmp)
二、返回函数
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
def lazy_sum(*args): def sum(): ax = 0 for n in args: ax = ax + n return ax return sum
调用lazy_sum不会立即返回计算的值,而是返回sum函数对象
>>> f = lazy_sum(1, 3, 5, 7, 9) >>> f <function sum at 0x10452f668>
再次调用 f 才会真正返回求和的值
>>> f()
25
在这个例子中,我们在函数lazy_sum
中又定义了函数sum
,并且,内部函数sum
可以引用外部函数lazy_sum
的参数和局部变量,当lazy_sum
返回函数sum
时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
三、匿名函数
匿名函数lambda x: x * x
实际上就是:
def f(x): return x * x
关键字lambda
表示匿名函数,冒号前面的x
表示函数参数。
匿名函数有个限制,就是只能有一个表达式,不用写return
,返回值就是该表达式的结果。
四、装饰器
五、偏函数
使用functools里的partial建立偏函数
>>> import functools >>> int2 = functools.partial(int, base=2) >>> int2('1000000') 64 >>> int2('1010101') 85
functools.partial
的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。