接收函数为参数,或者把函数做为结果返回的函数为高阶函数。html
要求:仿照内建函数sorted,自行实现一个sort函数。内建函数sorted函数是返回一个新的列表,能够设置升序或降序,也能够设置一个排序的函数,自定义的sort函数也要实现这个功能。编程
sort函数实现思路:新建一个列表,遍历原列表,和新列表的值一次比较决定如何插入到新列表中。闭包
sort函数版本一的实现,代码以下:app
1 def sort(iterable): 2 ret = [] 3 for x in iterable: 4 for i, y in enumerate(ret): 5 if x > y: # 找到比ret中大的位置上的数插入相应位置,降序排序 6 ret.insert(i, x) 7 break 8 else: # 不大于,说明x在ret中是最小的,直接将其追加至ret后 9 ret.append(x) 10 return ret 11 12 if __name__ == '__main__': 13 lst = [1,2,3,4,5,6,7,8] 14 print(sort(lst))
上述代码只能实现的,升序的排列方式,那么如今想经过一个参数来控制排列的方式,该如何实现呢?看以下代码:ide
1 def sort(iterable, reverse=False): 2 ret = [] 3 for x in iterable: 4 for i, y in enumerate(ret): 5 flag = x > y if reverse else x < y # 默认排序方式为升序 6 if flag: # 找到比ret中大的位置上的数插入相应位置,降序排序 7 ret.insert(i, x) 8 break 9 else: # 不大于,说明x在ret中是最小的,直接将其追加至ret后 10 ret.append(x) 11 return ret
经过对reverse参数的boole值进行判断,看使用降序仍是升序,那么能不能将对x,y大小的判断的功能抽象出来,做为一个排序的函数传给sort函数?看以下代码:函数式编程
1 def comparator(x, y): 2 if x > y: 3 return False 4 else: 5 return True 6 7 def sort(iterable, reverse=False, key=None): 8 ret = [] 9 for x in iterable: 10 for i, y in enumerate(ret): 11 flag = key(x, y) if reverse else not key(x, y) 12 if flag: # 找到比ret中大的位置上的数插入相应位置,默认降序排序 13 ret.insert(i, x) 14 break 15 else: # 不大于,说明x在ret中是最小的,直接将其追加至ret后 16 ret.append(x) 17 return ret
该代码中在调用sort函数,每次都得传入一个函数才能实现排序,那么能不能用一个函数的表达式做为一个默认值参数进行传入呢?这就要用到匿名函数,代码以下:函数
1 def sort(iterable, reverse=False, key=lambda a,b:a>b): 2 ret = [] 3 for x in iterable: 4 for i, y in enumerate(ret): 5 flag = key(x, y) if not reverse else not key(x, y) 6 if flag: # 找到比ret中大的位置上的数插入相应位置,默认降序排序 7 ret.insert(i, x) 8 break 9 else: # 不大于,说明x在ret中是最小的,直接将其追加至ret后 10 ret.append(x) 11 return ret
一步一步的将代码实现到这,已经将sort函数从最初实现的简单排序,改为最终的能够设置升序和排序,以及设置排序的规则的函数。这样就将sort函数改为了一个高阶函数。学习
sorted(iterable[, key][, reverse]),内置函数sorted函数中可选的key参数用于提供一个函数,它会应用到各个元素上进行排序。例如,若是想根据单词的长度进行排序,只需将len函数传给key参数,以下示例:spa
任何单参数函数都能做为key参数的值,再好比实现:将每一个单词的字母反转后,在对其进行排序。实现以下:3d
在函数式编程中,Python 3中经常使用的高阶函数还有,map、filter。
filter(function, iterable),过滤可迭代对象的元素,返回一个迭代器。function是一个具备单参数的函数,返回bool值。
1 list(filter(lambda x: x%3==0, [1,9,55,150,-3,78,28,123])) # 过滤出数列中能被3整除的数字
map(function, *iterables),对多个可迭代对象的元素按照指定的函数进行映射,返回一个迭代器。
list(map(lambda x:2*x+1, range(5))) dict(map(lambda x: (x%5,x) , range(500)))
在Python 3中,map和filter返回生成器(一种迭代器),所以如今它们的直接替代品是列表推导式和生成器表达式。
柯里化指的是将原来接收两个参数的函数变成新的接收一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。其形式至关于将z = f(x, y)转换成z = f(x)(y)的形式。举例:
1 # 将加法函数柯里化 2 def add(x, y): 3 return x + y 4 5 # 柯里化 6 def add(x): 7 def inc(y): 8 return x + y 9 return inc 10 11 foo = add(2) 12 print(foo(3)) 13 # 至关于 14 print(add(2)(3))
经过柯里化的过程可知,在柯里化时使用嵌套函数就能够将函数转换成柯里化函数。
从前面的闭包,以及如今的高阶函数以及函数的柯里化,这些都是Python装饰器的基础,有了这些基础,就能够学习Python中的装饰器。
原文出处:https://www.cnblogs.com/dabric/p/11691824.html