第十三章 - Python高阶函数、柯里化
高阶函数
- First Class Object
- 函数在Python中是一等公民
- 函数也是对象,可调用的对象
- 函数可以作为普通变量、参数、返回值等等
- 高阶函数
- 数学概念 y=g(f(x))
- 在数学和计算机科学中,高阶函数应当是至少满足下面一个条件的函数
- 接受一个或多个函数作为参数
- 输出一个函数
高阶函数
- 计数器
def counter(base):
def inc(step=1):
base += step
return base
return inc - 分析:
- 函数couter是不是一个高阶函数?# 只要满足上面一个条件,就是高阶函数。
- 上面代码有没有什么问题?怎样改进 # base是counter的本地变量,base在inc新的变量赋值,所以会报错
- 如何调用完成计数功能
- f1 = counter(5)和f2=counter(5),请问f1和f2相等吗?
可以把内层函数inc看成counter的本地变量,压栈时都会重新生成
- 函数couter是不是一个高阶函数?# 只要满足上面一个条件,就是高阶函数。
自定义sort函数
- 排序问题
- 仿照内建函数sorted,请自行实现一个sort函数(不使用内建函数),能够为列表元素排序
- 思路
- 内建函数sorted函数是返回一个新的列表,可以设置升序或降序,可以设置一个排序的函数。
自定义的sort函数也要实现这个功能 - 新建一个列表,遍历原列表,和新列表的值依次比较决定如何插入到新列表中
- 内建函数sorted函数是返回一个新的列表,可以设置升序或降序,可以设置一个排序的函数。
- 思考
- sorted函数的实现原理,扩展到map、filter函数的实现原理
自定义sort函数
- sort函数实现。下面实现的什么排序?还能怎么改变
def sort(iterable):
ret = [ ]
for x in iterable:
for i, y in enumerate(ret):
if x > y: # 找到大的就地插入。如果换成x < y呢,函数什么意思呢?
ret.insert(i,x) # 降序
break
else: # 不大于,说明是最小的,尾部追加
ret.append(x)
return ret
print(sort([1,2,5,4,2,3,5,6]))
自定义sort函数
sort函数实现。用一个参数控制顺序
def sort(iterable, reverse=False):
ret = []
for x in iterable:
for i, y in enumerate(ret):
flag = x>y if reverse else xif flag: # 是否能进一步改进
ret.insert(i,x)
break
else:
ret.append(x)
return ret
print(sort([1,2,5,4,2,3,5,6]))x>y 这种比较逻辑比较死,可以改成灵活的函数。
def sort(iterable, reverse=False):
def comp(a, b):
return a>b if reverse else a ret = []
for x in iterable:
for i, y in enumerate(ret):
if comp(x, y):
ret.insert(i,x)
break
else:
ret.append(x)
return ret
print(sort([1,2,5,4,2,3,5,6]))comp 是内部函数,别人用不了,要放到外面
def comp(a, b, reverse):
return a>b if reverse else a
def sort(iterable, reverse=False):
ret = []
for x in iterable:
for i, y in enumerate(ret):
if comp(x, y, reverse):
ret.insert(i,x)
break
else:
ret.append(x)
return ret
print(sort([1,2,5,4,2,3,5,6]))
- 把sort写成高阶函数形式
def comp(a, b):
return a < b
def sort(iterable, key=comp, reverse=False):
ret = []
for x in iterable:
for i, y in enumerate(ret):
flag = key(x, y) if reverse else key(y, x)
if flag:
ret.insert(i,x)
break
else:
ret.append(x)
return ret
print(sort([1,2,5,4,2,3,5,6]))
- comp是一行函数,可以写成 lambda 表达式
自定义sort函数
- sort函数实现。下面实现的什么排序?还能怎么改变
def sort(iterable, key=lambda a,b : a>b):
ret = [ ]
for x in iterable:
for i, y in enumerate(ret):
if key(x, y): # 函数的返回值是bool
ret.insert(i,x)
break
else:
ret.append(x)
return ret
print(sort([1,2,5,4,2,3,5,6]), lambda a,b:a>b) # 升序还是降序?如何反序?
自定义sort函数
- sort函数实现
def sort(iterable, reverse=False, key=lambda x,y:xret = []
for x in iterable:
for i,y in enumerate(ret):
flag = key(x,y) if not reverse else not key(x,y)
if flag:
ret.insert(i, x)
break
else:
ret.append(x)
return ret
print(sort([1,2,5,4,2,3,5,6]))
内建函数-高阶函数
- sorted(iterable[, key][, reverse])
- 排序
- filter(function, iterable) --> filter object
- 过滤数据
- map(func, *iterables) --> map object
- 映射
内建函数-高阶函数
- sorted(iterable[, key][, reverse]) 排序
- 返回一个新的列表,对一个可迭代对象的所有元素排序,排序规则为key定义的函数,reverse表示是否排序翻转
- sorted(lst,key=lambda x:6-x) # 返回新列表
key只能对一个元素操作,与我们前面自己写的不同,前面的key是x,y对两个元素操作。
key只是对元素生成一个新的临时元素用来比较,并不会修改原来的元素。这里6-x只是计算出一个临时值。用来比较的。
比较完,添加的是原本的值到新序列中。举例list是[1,2,3,4,5,6],那么比较的结果就是[6,5,4,3,2,1] - list.sort(key=lambda x: 6-x) # 就地修改
内建函数-高阶函数
- filter(function, iterable)
- 过滤可迭代对象的元素,返回一个迭代器(迭代器是惰性求值)
- function一个具有一个参数的函数,返回bool
- 例如,过滤出数列中能被3整除的数字
list(filter(lambda x: x%3==0, [1,9,55,150,-3,78,28,123]))
- 过滤可迭代对象的元素,返回一个迭代器(迭代器是惰性求值)
- map(function, *iterables) --> map object
- 对可迭代对象的元素按照指定的函数进行映射(就是把元素当成key得到value),返回一个迭代器
- list(map(lambda x:2*x+1, range(5)))
- dict(map(lambda x: (x%5,x) , range(500)))
*iterables意思是收集n个可迭代对象,%5说明key不会超过5
- 对可迭代对象的元素按照指定的函数进行映射(就是把元素当成key得到value),返回一个迭代器
柯里化 Currying
- 柯里化
- 指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数
- z = f(x, y) 转换成 z = f(x)(y)的形式
- 举例
- 将加法函数柯里化
def add(x, y):
return x + y - 转换如下
def add(x):
def _add(y):
return x+y
return _add
add(5)(6)
- 将加法函数柯里化
- 通过嵌套函数(返回值是函数)就可以把函数转换成柯里化函数
最后
本文的另外链接是:https://herodanny.github.io/python-magedu-2018-notes20.html