python 函数式编程库_python进阶-函数式编程库toolz用法介绍-part2

在第一部分简单介绍了python的函数式编程基本方法后,从这部分开始将开始更深入的学习toolz的使用方法。话不多说,下面开始上示例代码。

将上一部分的函数拿来继续用

def add(x, y):

return x + y

def mul(x, y):

return x * y

def lesser(x, y):

if x < y:

return x

else:

return y

def greater(x, y):

if x > y:

return x

else:

return y

首先是accumulate的用法,功能类似于numpy的累加,不过操作(加、乘或其他计算)具体由传入的第一个参数来决定;又可以看出和reduce相近,只不过reduce只返回最后的结果

import numpy as np

X[X>=10].cumsum()

# >>>array([ 10, 21, 33, 46, 60, 75, 91, 108, 126, 145], dtype=int32)

data = range(10, 20)

list(accumulate(add, data))

# >>>[10, 21, 33, 46, 60, 75, 91, 108, 126, 145]

from functools import reduce

reduce(add,data)

# >>>145

继续来看map、reduce、accumulate的更灵活的一些用法,

data1 = [1, 2, 3, 4, 5]

data2 = [10, 20, 30, 40, 50]

list(map(add, data1, data2))

# >>>[11, 22, 33, 44, 55]

reduce(lesser, [5, 3, 2, 7, 3], 999999999) # 注意第三个参数为初值

# >>> 2

reduce(lesser, [5, 3, 2, 7, 3], 1)

# >>> 1

list(accumulate(lesser, [5, 3, 2, 7, 3]))

# >>> [5, 3, 2, 2, 2]

可以看出map、reduce、accumulate的第一个参数需要传入一个两个参数的函数(类似于双目运算符)。

到现在为止,热身活动已经结束了,开始介绍下面重要的一个概念,函数的柯里化(Currying,中文翻译还是有些怪,看英文有可能突然想到投3分的库里啊)。首先介绍python中的几种处理高阶函数(higher order function)的方式,高阶函数可以简单理解为函数的函数,即函数可以当做变量传来传去,从而达到更灵活的用法。

#方式1 普通函数

def cumsum(data):

return accumulate(add, data)

#方式2 匿名函数

cumsum = lambda data: accumulate(add, data)

#方式3 偏函数

from functools import partial

cumsum = partial(accumulate, add)

#三种方式都是下面一个结果

list(cumsum(data))

# >>>[10, 21, 33, 46, 60, 75, 91, 108, 126, 145]

我们用高阶函数的方式实现了一个输出每步累加值的函数cumsum,除了普通函数的方式外,另外两种方式个人感觉都还算pythonic,选哪种看个人喜好了。

同样的功能,更函数式的方式,下面轮到神射手curry出场了!

from toolz import curry

mul_cur = curry(mul)

mul_cur(2) # 传入参数后返回一个函数,然后就剩下一个参数可传了

# >>>

mul_cur(2)(3)

# >>> mul_cur(2)(3)

# 方式4 currying的方式

accumulate = curry(accumulate)

cumsum = accumulate(add)

用斐波那契函数的例子来说明一下稍微复杂一点的情况,生成斐波那契数列的前10个数字,但是又不想(或者不能)改变fib函数的前提下(虽然我知道这样执行效率低),通过curry来得到了一个新的函数,相比于直接用列表展开或者每次都用map去做的话,肯定是更加方便快捷,并且通过新的函数名提高了程序的可读性。

def fib(n):

a, b = 0, 1

for i in range(n):

a, b = b, a + b

return b

fib(9)

# >>> 55

map = curry(map)

fibMany = map(fib)

list(fibMany(range(10)))

# >>> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

最后,告诉大家其实没必要每次都用curry去“包裹”一次map,toolz里面做好准备工作,提供了相关的柯里化好的函数。

from toolz.curried import map, accumulate, reduce, filter

# 函数很多就不一一列举了, 这些都等价于下面手动柯里化

from toolz import map, curry

map = curry(map)

未完待续 ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值