5月6日读书笔记——流畅的python

5.10 5.10 5.10 支持函数式编程的包
函数式编程的本质是什么?

这个“函数”的概念并不是指计算机中的函数,而是指数学中的函数,即自变量的映射。

也就是说,一个函数的值仅仅取决于函数参数的值,不依赖其他状态。例如sqrt(x)函数计算x的平方根,只要x不变,不论什么时候被调用,被调用了几次,都是一个结果。

函数式编程与命令式编程最大的不同其实在于:
函数式编程关心数据的映射(类型或代数结构之间的关系),命令式编程关心解决问题的步骤。

所谓映射,说白了就是一种东西和另一种东西之间的对应关系。
命令式编程中,你要做什么事情,要把完成目的的步骤详细描述出来,然后交给机器去运行。

那么函数式的风格,则是更注重在“对映射的描述”上。这样写出来的代码易推理,不易出错。

operator和functools等包的支持下,python可以轻松实现函数式编程。

示例如下:

>>> from functools import reduce
>>> def fact(n):
...     return reduce(lambda a,b: a*b, range(1, n+1))
... 
>>> fact(3)
6

另一种方式:

>>> from operator import mul
>>> def fact(n):
...     return reduce(mul, range(1, n+1))
... 
>>> fact(3)
6

operator模块为许多算术运算符提供了对应的函数,也避免了使用匿名函数这种复杂的写法。

operator模块中还有一类的函数(itemgetter,attrgetter),可以替代从序列中取出元素或者读取对象属性的lambda表达式。

>>> students = [('liu',18,(170,50)),('qi',20,(165,43)),('ss',23,(163,44))]
>>> from operator import itemgetter      
>>> for s in sorted(students, key=itemgetter(1)):
...     print(s)
... 
('liu', 18, (170, 50))
('qi', 20, (165, 43))
('ss', 23, (163, 44))

>>> for s in sorted(students, key=itemgetter(2)):
...     print(s)
... 
('ss', 23, (163, 44))
('qi', 20, (165, 43))
('liu', 18, (170, 50))

>>> s_name = itemgetter(1,0)
>>> for s in students:
...     print(s_name(s))
... 
(18, 'liu')
(20, 'qi')
(23, 'ss')

可以得知itemgetter的用途在于根据元组中的某个字段给元组列表进行排序。

attrgetter于itemgetter类似,它创建的函数会根据名称提取对象的属性。如果将多个属性名传给attrgetter,它会返回提取的值构成的元组。

使用functools.partial冻结参数

这个高阶函数用于部分应用一个函数。部分应用是指,基于一个函数创建一个新的可调用的对象,将原函数的某些参数固定。使用这个函数可以将一个接受1或多个参数的函数改编成需要回调的API,这样参数更少。

>>> from functools import partial
>>> triple = partial(mul, 3)
>>> triple(7)
21
>>> list(map(triple, range(1,10)))
[3, 6, 9, 12, 15, 18, 21, 24, 27]

>>> triple
functools.partial(<built-in function mul>, 3)

在这个例子中,函数本身需要两个参数,而partial将它变成了单参数,因为它将mul这个参数固定了。

partial返回的是一个functools.partial对象。该对象提供了访问原函数和固定参数的属性。

有了这些函数,函数式编程就不太需要功能有限的lambda表达式了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值