函数式编程
高阶函数
-
map()
:map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。 -
reduce ()
:reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。 -
filter()
:filter()函数用于过滤序列,返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。 -
sorted()
:排序函数,可以接收一个key函数来实现自定义的排序
`map()`
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
`reduce()`
>>> from functools import reduce
>>> def add(x, y):
... return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25
`filter()`
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
# 结果: ['A', 'B', 'C']
`sorted()`
def by_name(t):
return t.lower()
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=by_name, reverse=True)
也可以写成 sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
埃氏筛法:计算素数的一个方法
首先,列出从2开始的所有自然数,构造一个序列:
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
取序列的第一个数2,它一定是素数,然后用2把序列的2的倍数筛掉:
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
取新序列的第一个数3,它一定是素数,然后用3把序列的3的倍数筛掉:
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
取新序列的第一个数5,然后用5把序列的5的倍数筛掉:
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
不断筛下去,就可以得到所有的素数。
实现如下:
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) # 构造新序列
# 打印1000以内的素数:
for n in primes():
if n < 1000:
print(n)
else:
break
返回函数与闭包:函数返回函数,就叫闭包
例:利用闭包返回一个计数器函数,每次调用它返回递增整数:
def createCounter():
def plus():
a = 0
while True:
a = a + 1
yield a
f = plus()
def counter():
return next(f)
return counter
>>> f1 = createCounter()
>>> f1()
1
>>> f1()
2
匿名函数:使用关键字
lambda
表示,只能有一个表达式,是一个函数对象
>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
相当于
def f(x):
return x * x
>>> list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
//print
[1, 4, 9, 16, 25, 36, 49, 64, 81]
装饰器:在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
python函数修饰符@
的作用是为现有函数增加额外的功能,常用于插入日志、性能测试、事务处理等等。
@
:引用已有的函数,对下面的函数进行修饰。引用函数必须放在修饰函数的上面,引用函数的返回值,返回给被修饰的函数
#定义了一个装饰器,打印一个方法执行用时
def metric(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
f = func(*args, **kwargs)
end = time.time()
print('call %s excuted :%s ms' % (func.__name__, end-start))
return f
return wrapper
#用法
@metric
def fast(x, y):
time.sleep(1.0)
return x + y;
>>> print(fast(1,2))
call fast excuted :1.0020699501037598 ms
3
偏函数:
functools.partial
把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
>>> import functools
>>> sorted2 = functools.partial(sorted,key=abs)
>>> sorted2([1,-3,5,2,-4])#此处省略了key参参数.跟定义一个新函数一样理解
#等价于 sorted([1,-3,5,2,-4], key=abs)
[1, 2, -3, -4, 5]
参考资料:
https://www.liaoxuefeng.com/wiki/1016959663602400/1017328525009056