41°

python中的lambda+reduce(第二弹)

In [1]: add1 = lambda x : x+1

In [2]: add1
Out[2]: <function __main__.<lambda>(x)>

In [3]: add1(1)
Out[3]: 2

add1是一个函数类型

In [4]: add2 = lambda x : lambda y, z : x+y+z

In [5]: add2
Out[5]: <function __main__.<lambda>(x)>

In [6]: add2(1)
Out[6]: <function __main__.<lambda>.<locals>.<lambda>(y, z)>

In [7]: add2(1)(2,3)
Out[7]: 6

add2和add2(1)都是函数类型,lambda函数从外层向内层解析,若先传入两个参数则报错,解析完第一层返回的仍然是一个函数。

In [8]: import functools

In [9]: def compose(*functions):
   ...:     return functools.reduce(lambda f,g : lambda x:g(f(x)), functions, lambda x : x)
   ...:
   ...:

In [10]: compose(lambda x:2*x)
Out[10]: <function __main__.<lambda>(x)>

In [11]: compose(lambda x:2*x)(1)
Out[11]: 2

In [12]: compose(lambda x:2*x, lambda x: 3*x)
Out[12]: <function __main__.compose.<locals>.<lambda>.<locals>.<lambda>(x)>

In [13]: compose(lambda x:2*x, lambda x: 3*x)(1)
Out[13]: 6

functools.reduce函数有三个位置参数,第一个是函数;第二个是可迭代对象;第三个是参数的初始值,可以不设定。reduce函数一次可以从可迭代对象中传入两个值,前两个参数经过函数运算得到的结果作为第一个参数,再传入可迭代对象中的第三个参数,依次执行下去,直到可迭代对象完成迭代,得到结果。

In [14]: def compose_1(*functions):
    ...:     return functools.reduce(lambda f,g : lambda x:g(f(x)), functions, lambda x : x+1)
    ...:
    ...:

In [15]: compose_1(lambda x:2*x)
Out[15]: <function __main__.compose_1.<locals>.<lambda>.<locals>.<lambda>(x)>

In [16]: compose(lambda x : x+1, lambda x:2*x)
Out[16]: <function __main__.compose.<locals>.<lambda>.<locals>.<lambda>(x)>

In [17]: compose_1(lambda x:2*x)(1)
Out[17]: 4

In [18]: compose(lambda x : x+1, lambda x:2*x)(1)
Out[18]: 4

In [19]: compose_1(lambda x:2*x, lambda x: 3*x)
Out[19]: <function __main__.compose_1.<locals>.<lambda>.<locals>.<lambda>(x)>

In [20]: compose(lambda x : x+1, lambda x:2*x, lambda x: 3*x)
Out[20]: <function __main__.compose.<locals>.<lambda>.<locals>.<lambda>(x)>

In [21]: compose_1(lambda x:2*x, lambda x: 3*x)(1)
Out[21]: 12

In [22]: compose(lambda x : x+1, lambda x:2*x, lambda x: 3*x)(1)
Out[22]: 12

用compose和compose_1对比只想说明,添加初始化项(第三个参数),就相当于在可迭代对象的最前方加入这个初始化项。

In [23]: def compose_2(*functions):
    ...:     return functools.reduce(lambda f,g : lambda x:f+g+x, functions)
    ...:
    ...:

In [24]: compose_2(1)
Out[24]: 1

In [25]: compose_2(2)
Out[25]: 2

In [26]: compose_2(lambda x:2*x)
Out[26]: <function __main__.<lambda>(x)>

In [27]: compose_2(lambda x:2*x)(1)
Out[27]: 2

通过compose和compose_2对比,想说明,如果传入的可迭代对象只有一个参数,那么将只会原样输出,与之后的内层函数将没有关系,所以需要传入第三个位置参数

In [28]: def compose_3(*functions):
    ...:     return functools.reduce(lambda f,g : lambda x:f+g+x, functions, 1)
    ...:
    ...:

In [29]: compose_3(1)
Out[29]: <function __main__.compose_3.<locals>.<lambda>.<locals>.<lambda>(x)>

In [30]: compose_3(1)(1)
Out[30]: 3

以上就是传入了第三个位置参数,当可迭代对象只有一个参数时,也可正常计算。

这是第二次梳理这个知识点,之前写过博客,但是长久不用忘了,就重新梳理整理了思路。如果这篇介绍的不清楚可以结合上一篇理解。

原文链接:https://www.cnblogs.com/liuxuanhe/p/10911020.html

全部评论: 0

    我有话说: