公众号关注 “ML_NLP
设为 “星标”,重磅干货,第一时间送达!
作者:张生荣 
来源:zhangshengrong.com/p/O3aA7r2kX4
Python的functools模块中有一种函数叫“偏函数”,自从接触它以来,发现确实是一个很有用且简单的函数,相信你看完这篇文章,你也有相见恨晚的感觉。
我们都知道,函数入参可以设置默认值来简化函数调用,而偏函数的作用就是将入参进行默认填充,降低函数使用的难度。
如int()函数,可以将字符型转换为整型,且默认的都是以十进制形式来转换,那为什么一定是十进制呢?如果想用以二进制的形式转换呢?其实我们可以看一下int函数它本身的定义偏函数,一个让你相见恨晚的实用函数
可以看到int有两种用法,可以传一个位置参数,还可以多传一个关键字参数base,也就是基于什么格式转换,默认不传base参数是以十进制转换。所以,用二进制形式转换的话只要base=2即可(见下方代码)
value = int(
'10000'
)

print(value)  
# 10000

value = int(
'10000'
, base=
2
)

print(value)  
# 16
如果每次转换的字符串的时候都要输入base参数,显得很麻烦,因此偏函数的作用就体现出来了,可以使用functools.partial()函数来重新定义
from
 functools 
import
 partial


int2 = partial(int, base=
2
)

res = int2(
'10000'
)

print(res)   
# 16
到这里,你应该已经感觉到了偏函数的一点点魅力吧,那我们再从多个角度进一步看透它。
自定义函数的使用
defadd(a, b, c):
  print(
'a='
,a,
'b='
,b,
'c='
,c)

return
 a + b + c


add10 = partial(add, 
10
)

res = add10(
1
2
)   
# a= 10 b= 1 c= 2
如上代码中,partial(add, 10)入参并没有指定哪个关键字参数,函数却默认的将这个值传给了第一个参数a,那就说明,当没有指定默认参数时,默认赋值给第一个参数,余下参数按位置参数赋值。
当入参为可变参数时
defsum(*args):
  s = 
0
for
 n 
in
 args:

    s += n

return
 s


sum10 = partial(sum, 
10
)

print(sum10(
1
))  
# 11
print(sum10())   
# 10
按上述理解,没有指定默认参数时,默认赋给第一个参数,那么第一个参数永远是10,后面再传入参的话就从第二个参数开始计算,因此会实现10 + 1 = 11 的结果。同样,如果不继续传参的话,只有默认的10,所以结果就是10
当入参为可变关键字参数时
D = {
'value1'
:
10
'value2'
:
20
}

V = {
'Default'
:
100
}

defshow(**kw):
for
 k 
in
 kw:

    print(k, kw.get(k))


showDef = partial(show, **V)

showDef(**D)

# Default 100
# value1 10
# value2 20
同理,此时入参由于是可变参数,因此默认是第一个传入,先打印Default关键字,这里关注一下函数的写法,可变关键字参数要写成(**V)
当入参为限制的关键字参数时
defstudent(name, * , age, city):
  print(
'name:'
,name, 
'age:'
,age, 
'city:'
,city)


studentAge = partial(student, age=
20
)

studentAge(
'Tom'
,
'Beijing'
)

# TypeError: student() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given
我们知道,当用*号分隔开,表示后面的关键字参数是必传的,因此对于默认参数也是同样适用,即当参数为必传时,偏函数也需要对每个关键字参数设置默认值。因此修改后为
studentAge = partial(student, age=
20
, city=
'Beijing'
)

studentAge(
'Tom'
# name: Tom age: 20 city: Beijing
综上,偏函数可以将目标函数的部分参数固化后,重新定义为新的函数,降低了编码的复杂度,尤其是当参数很多的时候,或者只用到其中某些参数的场景下时,效果更为显著。
到这里,你是否有了相见恨晚的感觉呢?简单函数小技巧,非常实用的偏函数用法就介绍完了.
仓库地址共享:
在机器学习算法与自然语言处理公众号后台回复“代码”
即可获取195篇NAACL+295篇ACL2019有代码开源的论文。开源地址如下:https://github.com/yizhen20133868/NLP-Conferences-Code
重磅!忆臻自然语言处理-Pytorch交流群已正式成立
群内有大量资源,欢迎大家进群学习!
注意:请大家添加时修改备注为 [学校/公司 + 姓名 + 方向]
例如 —— 哈工大+张三+对话系统。
号主,微商请自觉绕道。谢谢!
继续阅读
阅读原文