高阶函数,柯里化,sort排序
高阶函数概念
first class object:
函数在python中时一等公民.
函数也是对象,可调用的对象.
函数可以作为普通变量,参数,返回值等等.
高阶函数:
数学概念: y=g(f(x)).
在数学和计算机科学中,高阶函数应当是至少满足下面一个条件的函数:
接受一个或多个函数作为参数.
输出一个函数.
计数器:
def counter(base):
def inc(step=1):
base += step
return base
return inc
# print(counter(5)())
res = counter(5)
print(res())
分析:
函数counter是一个高阶函数.
该函数运行会报错,原因在于第3行, base = base + step, base被重新赋值.
改进: 使用nonlocal.
nonlocal会指引inc去上层非全局作用域的本地作用域中查找.
改进之后的counter函数,f1 = counter(5)和f2 = counter(5).
比较f1和f2,值相同,但内存地址不同.因为inc是counter内的函数,每次调用counter,inc都要在栈上重新生成对象,故内存地址不相等.
自定义sort函数
排序问题: 仿照内建函数sorted,实现一个sort函数(不使用内建函数),能够为列表元素排序.
思路:
内建函数sorted会返回一个新的列表,可以设置升序或降序,设置的排序的函数,自定义的sort函数也要实现这个功能.
新建一个列表,遍历原列表,和新列表的值依次比较决定如何插入到新列表中.
for函数的使用原则: 不建议修改源,除非明确知道需要修改,因为不一定只给一个人用,所以要选择使用sort和sorted.
实现示例:
def sort(iterable):
ret = []
for x in iterable:
for i, y in enumerate(ret):
if x < y:
ret.insert(i, x)
break
else:
ret.append(x)
return ret
print(sort([1, 9, 5]))
sort函数实现,用一个参数控制顺序:
def sort(iterable, reverse=False):
ret = []
for x in iterable:
for i, y in enumerate(ret):
flag = x > y if reverse else x < y
if flag:
ret.insert(i, x)
break
else:
ret.append(x)
return ret
print(sort([1, 9, 5], reverse=True))
def sort(iterable, fn = lambda a, b : a < b):
ret = []
for x in iterable:
for i, y in enumerate(ret):
if fn(x, y):
ret.insert(i, x)
break
else:
ret.append(x)
return ret
print(sort([1, 9, 5]))
内建函数-高阶函数
sorted(iterable[,key][,reverse]) 排序.
返回一个新的列表,对一个可迭代对象的所有元素排序,排序规则为key定义的函数, reverse表示是否翻转.
sorted(lst, key=lambda x:6-x) # 返回新列表.
list.sort(key=lambda x:6-x) # 就地修改.
filter(function,iterable) -> filter object
过滤可迭代对象的元素,返回一个迭代器.
function一个具有一个参数的函数, 返回bool.
例: 过滤出列表中能被3整除的数字.
list(filter(lambda x: x % 3 == 0, [1,9,55,150,-3,78,28,123])
map(func, iterables) -> map object
对多个可迭代对象的元素按照指定的函数进行映射,返回一个迭代器.
list(map(lambda x:2x+1, range(5)))
dict(map(lambda x: (x%5,x) , range(500)))
注:
sort和map不改变元素个数.
filter可能会改变元素个数.
柯里化Currying
柯里化:
指将原来接收两个参数的函数变成新的接收一个参数的函数的过程, 新的函数返回一个以原有第二个参数为参数的函数.
z = f(x, y) 转换成 z = f(x)(y) 的形式.
举例: 将加法柯里化
def add(x, y):
return x + y
print(add(5, 4))
def add(x):
def _add(y):
return x + y
return _add
print(add(5)(4))
以上通过嵌套函数就可以把函数转换为柯里化函数.