filter
Python内建的filter()
函数用于过滤序列。
map()
类似,filter()
也接收一个函数和一个序列。和map()
不同的是,filter()
把传入的函数依次作用于每个元素,然后根据返回值是True
还是False
决定保留还是丢弃该元素。
用filter()
这个高阶函数,关键在于正确实现一个“筛选”函数。
注意到filter()
函数返回的是一个Iterator
,也就是一个惰性序列,所以要强迫filter()
完成计算结果,需要用list()
函数获得所有结果并返回list。
得到所有的素数。
def _odd_iter(): n = 1 while True: n = n + 2 yield n
定义一个筛选函数:
def _not_divisible(n): return lambda x: x % n > 0
定义一个生成器,不断返回下一个素数:
def primes(): yield 2 it = _odd_iter() # 初始序列 while True: n = next(it) # 返回序列的第一个数 yield n it = filter(_not_divisible(n), it) # 构造新序列
这个生成器先返回第一个素数2
,然后,利用filter()
不断产生筛选后的新的序列。
由于primes()
也是一个无限序列,所以调用时需要设置一个退出循环的条件:
打印1000以内的素数:for n in primes(): if n < 1000: print(n) else: break
注意到Iterator
是惰性计算的序列,所以我们可以用Python表示“全体自然数”,“全体素数”这样的序列,而代码非常简洁。
我这里没有做相关的实验
sorted
sorted()
函数也是一个高阶函数,它还可以接收一个key
函数来实现自定义的排序,例如按绝对值大小排序:
sorted([36, 5, -12, 9, -21], key=abs) [5, 9, -12, -21, 36]
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
进行反向排序,不必改动key函数,可以传入第三个参数reverse=True
:
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
返回函数
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
f1==f2
[图片上传中。。。(1)]
函数名 与 调用函数 f1()
匿名函数
匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:
f = lambda x: x * x f(5)
list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
匿名函数有个限制,就是只能有一个表达式
可以把匿名函数作为返回值返回
def build(x, y): return lambda: x * x + y * y
装饰器 **kw 什么意思?
装饰器
函数对象有一个name
属性,可以拿到函数的名字:
在函数调用前后自动打印日志,但又不希望修改now()
函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
def log(func): def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper
log
,因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。我们要借助Python的@语法,把decorator置于函数的定义处:
@logdef now(): print('2015-3-25')
把@log放到now()函数的定义处,相当于执行了语句:now = log(now)
一个完整的decorator的写法如下:
import functoolsdef log(func): @functools.wraps(func) def wrapper(*args, *kw): print('call %s():' % func.name) return func(args, **kw) return wrapper
或
import functoolsdef log(text): def decorator(func): @functools.wraps(func) def wrapper(*args, *kw): print('%s %s():' % (text, func.name)) return func(args, **kw) return wrapper return decorator
import functools
是导入functools
模块。模块的概念稍候讲解。现在,只需记住在定义wrapper()
的前面加上@functools.wraps(func)
即可。