1 Python高阶函数

  接收函数为参数,或者把函数作为结果返回的函数为高阶函数。

1.1 自定义sort函数

  要求:仿照内建函数sorted,自行实现一个sort函数。内建函数sorted函数是返回一个新的列表,可以设置升序或降序,也可以设置一个排序的函数,自定义的sort函数也要实现这个功能。

  sort函数实现思路:新建一个列表,遍历原列表,和新列表的值一次比较决定如何插入到新列表中。

  sort函数版本一的实现,代码如下:

 def sort(iterable):
ret = []
for x in iterable:
for i, y in enumerate(ret):
if x > y: # 找到比ret中大的位置上的数插入相应位置,降序排序
ret.insert(i, x)
break
else: # 不大于,说明x在ret中是最小的,直接将其追加至ret后
ret.append(x)
return ret if __name__ == '__main__':
lst = [1,2,3,4,5,6,7,8]
print(sort(lst))

  上述代码只能实现的,升序的排列方式,那么现在想通过一个参数来控制排列的方式,该如何实现呢?看如下代码:

 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中大的位置上的数插入相应位置,降序排序
ret.insert(i, x)
break
else: # 不大于,说明x在ret中是最小的,直接将其追加至ret后
ret.append(x)
return ret

  通过对reverse参数的boole值进行判断,看使用降序还是升序,那么能不能将对x,y大小的判断的功能抽象出来,作为一个排序的函数传给sort函数?看如下代码:

 def comparator(x, y):
if x > y:
return False
else:
return True def sort(iterable, reverse=False, key=None):
ret = []
for x in iterable:
for i, y in enumerate(ret):
flag = key(x, y) if reverse else not key(x, y)
if flag: # 找到比ret中大的位置上的数插入相应位置,默认降序排序
ret.insert(i, x)
break
else: # 不大于,说明x在ret中是最小的,直接将其追加至ret后
ret.append(x)
return ret

  该代码中在调用sort函数,每次都得传入一个函数才能实现排序,那么能不能用一个函数的表达式作为一个默认值参数进行传入呢?这就要用到匿名函数,代码如下:

 def sort(iterable, reverse=False, key=lambda a,b:a>b):
ret = []
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中大的位置上的数插入相应位置,默认降序排序
ret.insert(i, x)
break
else: # 不大于,说明x在ret中是最小的,直接将其追加至ret后
ret.append(x)
return ret

  一步一步的将代码实现到这,已经将sort函数从最初实现的简单排序,改成最终的可以设置升序和排序,以及设置排序的规则的函数。这样就将sort函数改成了一个高阶函数。

1.2 内建函数-高阶函数

1.2.1 sorted函数

  sorted(iterable[, key][, reverse]),内置函数sorted函数中可选的key参数用于提供一个函数,它会应用到各个元素上进行排序。例如,如果想根据单词的长度进行排序,只需将len函数传给key参数,如下示例:

  任何单参数函数都能作为key参数的值,再比如实现:将每个单词的字母反转后,在对其进行排序。实现如下:

  在函数式编程中,Python 3中常用的高阶函数还有,map、filter。

1.2.2 filter函数

  filter(function, iterable),过滤可迭代对象的元素,返回一个迭代器。function是一个具有单参数的函数,返回bool值。

 list(filter(lambda x: x%3==0, [1,9,55,150,-3,78,28,123]))  # 过滤出数列中能被3整除的数字

1.2.3 map函数

  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返回生成器(一种迭代器),因此现在它们的直接替代品是列表推导式和生成器表达式。

2 柯里化Currying

  柯里化指的是将原来接收两个参数的函数变成新的接收一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数。其形式相当于将z = f(x, y)转换成z = f(x)(y)的形式。举例:

 # 将加法函数柯里化
def add(x, y):
return x + y # 柯里化
def add(x):
def inc(y):
return x + y
return inc foo = add(2)
print(foo(3))
# 相当于
print(add(2)(3))

  通过柯里化的过程可知,在柯里化时使用嵌套函数就可以将函数转换成柯里化函数。

  从前面的闭包,以及现在的高阶函数以及函数的柯里化,这些都是Python装饰器的基础,有了这些基础,就可以学习Python中的装饰器。

Python高阶函数及函数柯里化的更多相关文章

  1. Java函数式编程:二、高阶函数,闭包,函数组合以及柯里化

    承接上文:Java函数式编程:一.函数式接口,lambda表达式和方法引用 这次来聊聊函数式编程中其他的几个比较重要的概念和技术,从而使得我们能更深刻的掌握Java中的函数式编程. 本篇博客主要聊聊以 ...

  2. 浅析 JavaScript 中的 函数 uncurrying 反柯里化

    柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是 ...

  3. python 高阶内置函数

    1.lambda 匿名函数 lambda 参数: 返回值 函数名统一都叫lambda. 2.sorted() 排序函数 排序函数 sorted(iterable,key,reverse) key:排序 ...

  4. JS的闭包、高阶函数、柯里化

    本文原链接:https://cloud.tencent.com/developer/article/1326958 https://cloud.tencent.com/developer/articl ...

  5. 从 ES6 高阶箭头函数理解函数柯里化

    前言:第一次看到多个连续箭头函数是在一个 react 项目中,然鹅确认了下眼神,并不是对的人,因为看得一脸懵逼.em......于是开始各种搜索,先是知道了多个连续箭头函数就是 es6 的多次柯里化的 ...

  6. js高阶函数应用—函数柯里化和反柯里化(二)

    第上一篇文章中我们介绍了函数柯里化,顺带提到了偏函数,接下来我们继续话题,进入今天的主题-函数的反柯里化. 在上一篇文章中柯里化函数你可能需要去敲许多代码,理解很多代码逻辑,不过这一节我们讨论的反科里 ...

  7. JavaScript函数柯里化

    函数式 JavaScript是以函数为一等公民的函数式语言.函数在JavaScript中也是一个对象(继承制Function),函数也可以作为参数传递成函数变量.最近几年函数式也因为其无副作用的特性. ...

  8. swift 学习(二)基础知识 (函数,闭包,ARC,柯里化,反射)

    函数 func x(a:Int, b:Int)  {}   func x(a:Int, b:Int) -> Void {}  func x(a:Int, b:Int) ->(Int,Int ...

  9. 浅析 JavaScript 中的 函数 currying 柯里化

    原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...

随机推荐

  1. Python入门基础:七段数码管绘制

    1.在学习Python的过程中,运用所学的一些基础知识,进行一些简单的编程,可以收获很多乐趣.在生活中,LED灯无处不在,荧幕显示的广告词,给我们呈现出动态的视觉效果.下面,则以最简单的显示日期为例, ...

  2. java8-Stream原理

    前言 java8新特性目前使用非常广泛,其中Stream更是最常用的特性,这篇文章将介绍Stream的原理,如果你现在还不怎么会用的话可以看一下菜鸟教 https://www.runoob.com/j ...

  3. 前端利器躬行记(5)——Git

    Git是一款开源的分布式版本控制系统,它的出现和Linux紧密相关.Linux内核项目组为了能更好地管理和维护Linux内核开发,于2002年开始启用商业的分布式版本控制系统BitKeeper.虽然软 ...

  4. Elastic Stack 笔记(七)Elasticsearch5.6 聚合分析

    博客地址:http://www.moonxy.com 一.前言 Elasticsearch 是一个分布式的全文搜索引擎,索引和搜索是 Elasticsarch 的基本功能.同时,Elasticsear ...

  5. jmeter性能分析

    1.硬件要求:包括客户端和服务端的cpu,mem,network,disk等,这些硬件设备必须满足性能测试的前提下,才能进行性能测试,否则得到的各项指标不一定是正确的 2.场景分析: 测试前的准备工作 ...

  6. Node.js之模块机制

    > 文章原创于公众号:程序猿周先森.本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号. ![file](https://img2018.cnblogs.com/blog/830272/20 ...

  7. MOOC C++笔记(四):运算符重载

    第四周:运算符重载 基本概念 运算符重载,就是对已有的运算符(C++中预定义的运算符)赋予多重的含义,使同一运算符作用于不同类型的数据时导致不同类型的行为. 运算符重载的目的是:扩展C++中提供的运算 ...

  8. Java中一维,二维数组的静态和动态初始化

    今天我们要开始来讲讲Java中的数组,包括一维数组和二维数组的静态初始化和动态初始化 数组概述: 数组可以看成是多个相同类型数据的组合,对这些数据的统一管理; 数组变量属于引用数据类型,数组也可以看成 ...

  9. Windows认证 | Windows本地认证

    Windows的登陆密码是储存在系统本地的SAM文件中的,在登陆Windows的时候,系统会将用户输入的密码与SAM文件中的密码进行对比,如果相同,则认证成功. SAM文件是位于%SystemRoot ...

  10. 用 C# 来守护 Python 进程

    背景 目前我主要负责的一个项目是一个 C/S 架构的客户端开发,前端主要是通过 WPF 相关技术来实现,后端是通过 Python 来实现,前后端的数据通信则是通过 MQ 的方式来进行处理.由于 Pyt ...