Python函数柯里化 python 柯里化

函数柯里化与不定参数处理

答案

创新互联公司服务项目包括五峰网站建设、五峰网站制作、五峰网页制作以及五峰网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,五峰网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到五峰省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

首先函数柯里化因为参数固定,使用vars数组保存每次传进来的参数,然后判断fn的参数个数,如果fn参数个数正好等于vars数组中保存的个数,那么执行fn,否则递归一次,返回curried函数,继续等待输入。这里外层curry 函数只会执行一次便会被剥离,之后add会变成curried的一个引用,同时curried可以闭包引用外层的vars,使得每次传入的参数可以长久保存。

参考上面网上优秀答案的思路,写出这个不定参数处理add函数,...args可以接受不定参数,由于题目二中并没有题目一中 const add = curry((a, b ,c ,d) = a + b + c +d) 函数劫持的过程,所以不能直接返回函数定义,而是要返回一个执行完的函数curried(...args),同时在curried中再返回一个函数定义curried,这样就可以把函数连接起来了。由于参数不定,这里对每次传入的参数都要进行执行处理,执行方法是利用函数的隐式转换,当函数执行结束时会有一个toString的操作,来使函数能参与其他的运算,这里我们将toString从新定义,返回vars中的累加值,从而实现add运算。

什么是函数柯里化

通过上面的定义可以看出,柯里化是一个函数返回另一个函数,这是一个典型的闭包,它封装了一部分不变的内容,然后去处理其他可变的数据

例如我们在使用ajax的时候url是不变的,但是传递的参数不同将返回不同的数据,那么我们就可以把url封装到一个函数里然后返回一个带参数的函数,通过返回的函数去处理不同参数的情况

上面的两个请求参数不同,但是请求的地址url是固定不变的。这就是柯里化,将不变的参数通过闭包的形式封装起来,然后去处理可变的参数

lodash中有一个柯里化方法 curry 。举个官网的例子:

具体用法官网说明很清楚我就不再赘述了。

Python 有哪些好玩的语法糖

当然是函数式那一套黑魔法啦,且听我细细道来。

lambda表达式

也就是匿名函数。

用法:lambda 参数列表 : 返回值

例:

+1函数

f=lambda x:x+1

max函数(条件语句的写法如下)

f_max=lambda x,y:x if xy else y

上述定义的函数与用def定义的函数没有区别,而且左边的f=在某些情况下并不是必要的。

filter,map,reduce

filter函数接受两个参数,第一个是过滤函数,第二个是可遍历的对象,用于选择出所有满足过滤条件的元素,不同版本的filter的返回值稍有区别,我用的是python3.5,filter返回的是经过过滤的可遍历对象。

例:

去除小写字母

s=filter(lambda x:not str(x).islower(),"asdasfAsfBsdfC")

for ch in s:

print(ch)

map函数接受的参数类型与filter类似,它用于把函数作用于可遍历对象的每一个元素。类似于数学中映射的概念。

例:

求y=2x+1(偷偷用了一下range函数生成定义域)

s=map(lambda x:2*x+1,range(6))

for x in s:

print(x)

reduce函数对每个元素作累计操作,它接受的第一个参数必须是有两个参数的函数。

例:

求和

from functools import reduce

s=reduce(lambda x,y:x+y,range(1,6))

print(s)

求乘积(第三个可选参数表示累计变量的初值)

from functools import reduce

s=reduce(lambda x,y:x*y,range(1,6),1)

print(s)

柯里化(curry)函数

如果一个函数需要2个参数,而你只传入一个参数,那么你就可以得到一个柯里化的函数,这是函数式编程语言的重要特性之一,遗憾的是,python并不能在语法层面支持柯里化调用,但它在库中提供了接口。

例:

*3函数

f_mul=lambda x,y:x*y

from functools import partial

mul3=partial(f_mul,3)

print(mul3(1))

print(mul3(6))

打包与解包

有点类似于函数式中的模式匹配,略牵强。

t=(1,2,3)

x,y,z=t

列表生成式

这个也有点牵强,不知道严格意义上讲属不属于函数式风格。

例:生成奇数序列

l=[2*x+1 for x in range(10)]

for i in l:

print(i)

最后来一个彩蛋(以前某答主提到的用调分函数来美颜的算法,忘了出处了,侵删)

from PIL import Image

from math import sqrt

im = Image.open("a.jpg")

ret= im.convert(mode="RGB")

ret = ret.point(lambda x:sqrt(x)*sqrt(255))

ret.save("b.jpg")

Python 实现自定义柯里化函数类?

答案中的方法使用函数装饰器实现

def currying(func, n=None):

n = n or func.__code__.co_argcount

def merge(*head):

  k = len(head)

  if k == n:

      return func(*head)

  elif k n:

      return currying(lambda *tail: func(*(head + tail)), n - k)

  elif k n:

      raise TypeError('Too many arguments:', head)

return merge

装饰器代码

通过对目标函数进行装饰,实现目标函数柯里化,原理是对目标函数的参数进行计数,当接收参数达到指定个数时进行计算,否则保存已有的参数,其中 currying 函数的第一个参数是目标函数,第二个参数是接收的参数数量,默认值为目标函数的参数个数。

示例代码

如上图代码所示,add3 函数使用 currying 函数装饰,即可实现柯里化

运行结果


分享名称:Python函数柯里化 python 柯里化
标题URL:http://pwwzsj.com/article/highgc.html