《流畅的Python》3-operator模块和functools模块


Python 提供 operator模块和 functools模块来方便地实现函数式编程。

operator模块

用lambda实现阶乘函数

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

operator模块的函数作用就是提供相应的函数,替代 lambda a,b:a*b这种不易理解的匿名函数。
例如 muladd

使用 itemgetter 排序一个元组列表。

itemgetter(num) 指定一个位置。

>>> metro_data = [
...     ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
...     ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
...     ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
...     ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
...     ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
... ]
>>>
>>> from operator import itemgetter
>>> for city in sorted(metro_data, key=itemgetter(1)):
...     print(city)
...
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889))
('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
('Mexico City', 'MX', 20.142, (19.433333, -99.133333))
('New York-Newark', 'US', 20.104, (40.808611, -74.020386))
>>> cc_name = itemgetter(1, 0)
>>> for city in metro_data:
...     print(cc_name(city))
...
('JP', 'Tokyo')
('IN', 'Delhi NCR')
('MX', 'Mexico City')
('US', 'New York-Newark')
('BR', 'Sao Paulo')

attritem 提取对象的属性。

attritemitemgetter相似
namedtupletuple的子集。提供了一个类似元祖的数据结构,并声明空的属性。

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

两者的关系相当于下标用字符串和数字去访问。

>>> from collections import namedtuple
>>> LatLong = namedtuple('LatLong', 'lat long')  # 定义 LatLong
>>> Metropolis = namedtuple('Metropolis', 'name cc pop coord')  # 再定义 Metropolis
>>> metro_areas = [Metropolis(name, cc, pop, LatLong(lat, long))  # 使用嵌套的元组拆包提取 (lat, long)
...     for name, cc, pop, (lat, long) in metro_data]
>>> metro_areas[0]
Metropolis(name='Tokyo', cc='JP', pop=36.933, coord=LatLong(lat=35.689722,
long=139.691667))
>>> metro_areas[0].coord.lat  # 深入 metro_areas[0],获取它的纬度。
35.689722
>>> from operator import attrgetter
>>> name_lat = attrgetter('name', 'coord.lat')  # 定义一个 attrgetter,获取 name 属性和嵌套的 coord.lat 属性。
>>>
>>> for city in sorted(metro_areas, key=attrgetter('coord.lat')):  # 使用 attrgetter,按照纬度排序城市列表。
...     print(name_lat(city))  # 使用定义的 attrgetter city,只显示城市名和纬度。
...
('Sao Paulo', -23.547778)
('Mexico City', 19.433333)
('Delhi NCR', 28.613889)
('Tokyo', 35.689722)
('New York-Newark', 40.808611)

methodcaller

operator.methodcaller(name[, args...])

Return a callable object that calls the method name on its operand. If additional arguments and/or keyword arguments are given, they will be given to the method as well. For example:

  • After f = methodcaller(‘name’), the call f(b) returns b.name().
  • After f = methodcaller(‘name’, ‘foo’, bar=1), the call f(b) returns b.name(‘foo’, bar=1).

个人理解和部分应用(partial application),冻结参数用法差不多,与functools.partial函数作用类似。

functools.partial 冻结参数

functools 模块提供一系列高阶函数,如 reduce 。冻结参数简单理解,把原函数的部分参数固定,返回一个新的函数。可以用于API封装。

The partial() is used for partial function application which “freezes” some portion of a function’s arguments and/or keywords resulting in a new object with a simplified signature. For example, partial() can be used to create a callable that behaves like the int() function where the base argument defaults to two:

举例:

>>> from operator import mul
>>> from functools import partial
>>> triple = partial(mul,3)  # 把第一个定位参数定为 3
>>> triple(4)  # 测试 triple 函数
12
>>> list(map(triple, range(10,20)))  # 在 map 中使用 triple , 这里不能使用mul.
[30, 33, 36, 39, 42, 45, 48, 51, 54, 57]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值