函数
高阶函数
map、 filter
>>> list(map(fact, range(6))) ➊
[1, 1, 2, 6, 24, 120]
>>> [fact(n) for n in range(6)] ➋
[1, 1, 2, 6, 24, 120]
>>> list(map(factorial, filter(lambda n: n % 2, range(6)))) ➌
[1, 6, 120]
>>> [factorial(n) for n in range(6) if n % 2] ➍
[1, 6, 120]
>>>
并不推荐使用map以及filter函数,而是用列表推导式.
reduce
>>> from functools import reduce ➊
>>> from operator import add ➋
>>> reduce(add, range(100)) ➌
4950
>>> sum(range(100)) ➍
4950
>>>
等是针对mul,这个还是比较方便的.
all(iterable)
如果 iterable 的每个元素都是真值,返回 True; all([]) 返回 True。
for c in words:
if c not in it:
break
# 改写为
all(c in it for c in words)
any(iterable)
只要 iterable 中有元素是真值,就返回 True; any([]) 返回 False。
可调用对象
如果想判断对象能否调用,可以使用内置的 callable() 函数。
只需实现实例方法 __call__
用户定义的函数的属性
| 名称 | 类型 | 说明 |
|---|---|---|
__annotations__ |
dict | 参数和返回值的注解 |
__call__ |
methodwrapper | 实现 () 运算符;即可调用对象协议 |
__closure__ |
tuple | 函数闭包,即自由变量的绑定(通常是 None) |
__code__ |
code | 编译成字节码的函数元数据和函数定义体 |
__defaults__ |
tuple | 形式参数的默认值 |
__get__ |
methodwrapper | 实现只读描述符协议(参见第 20 章) |
__globals__ |
dict | 函数所在模块中的全局变量 |
__kwdefaults__ |
dict | 仅限关键字形式参数的默认值 |
__name__ |
str | 函数名称 |
__qualname__ |
str | 函数的限定名称,如 Random.choice(参阅PEP 3155,https://www.python.org/dev/peps/pep-3155/) |
从定位参数到仅限关键字参数
def f(a, *, flag=False, **, ):
pass
为什么不写成def(a, flag=False),这是怕误传参数.
支持函数式编程的包
operator模块
- 使用 reduce 函数和一个匿名函数计算阶乘
from functools import reduce
def fact(n):
return reduce(lambda a, b: a*b, range(1, n+1))
- 使用 reduce 和 operator.mul 函数计算阶乘
from functools import reduce
from operator import mul
def fact(n):
return reduce(mul, range(1, n+1))
- attrgetter 与 itemgetter 作用类似,它创建的函数根据名称提取对象的属性。如果把多个属性名传给 attrgetter,它也会返回提取的值构成的元组。此外,如果参数名中包含 .(号), attrgetter 会深入嵌套对象,获取指定的属性。
>>> 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')
>>>
>>> from collections import namedtuple
>>> LatLong = namedtuple('LatLong', 'lat long') # ➊
>>> Metropolis = namedtuple('Metropolis', 'name cc pop coord') # ➋
>>> metro_areas = [Metropolis(name, cc, pop, LatLong(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 # ➍
35.689722
>>> from operator import attrgetter
>>> name_lat = attrgetter('name', 'coord.lat') # ➎
>>>
>>> for city in sorted(metro_areas, key=attrgetter('coord.lat')): # ➏
... print(name_lat(city)) # ➐
...
('Sao Paulo', -23.547778)
('Mexico City', 19.433333)
('Delhi NCR', 28.613889)
('Tokyo', 35.689722)
('New York-Newark', 40.808611)
- methodcaller 创建的函数会在对象上调用参数指定的方法,
>>> from operator import methodcaller
>>> s = 'The time has come'
>>> upcase = methodcaller('upper')
>>> upcase(s)
'THE TIME HAS COME'
>>> hiphenate = methodcaller('replace', ' ', '-')
>>> hiphenate(s)
'The-time-has-come
使用functools.partial冻结参数
数创建一个新的可调用对象,把原函数的某些参数固定。使用这个函数可以把接受一个或多个参数的函数改编成需要回调的 API,这样参数更少。
- 使用 partial 把一个两参数函数改编成需要单参数的可调用对象
>>> from operator import mul
>>> 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]
- 使用 partial 构建一个便利的 Unicode 规范化函数
>>> import unicodedata, functools
>>> nfc = functools.partial(unicodedata.normalize, 'NFC')
>>> s1 = 'café'
>>> s2 = 'cafe\u0301'
>>> s1, s2
('café', 'café')
>>> s1 == s2
False
>>> nfc(s1) == nfc(s2)
True
partialmethod
"""
>>> cell = Cell()
>>> cell.alive
False
>>> cell.set_alive()
>>> cell.alive
True
"""
from functools import partialmethod
class Cell(object):
def __init__(self):
self._alive = False
@property
def alive(self):
return self._alive
def set_state(self, state):
self._alive = bool(state)
set_alive = partialmethod(set_state, True)
set_dead = partialmethod(set_state, False)

浙公网安备 33010602011771号