标签:python 函数式编程、map、reduce、filter、sorted
变量可指向函数
>>> abs(-10)
10
>>> x = abs --x指向abs函数
>>> x(-1) --直接调用x
1
调用abs和调用x完全相同。
函数名也是变量
>>> abs = 10
>>> abs(-10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ‘int‘ object is not callable
传入函数(高阶函数)
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
简而言之:例如>>> abs(abs(-10)),这就是个高阶函数
>>> def add_abs(x, y, f):
... return f(x) + f(y)
...
>>>
>>> add_abs(-1, -2, abs)
3
Map和Reduce函数都是python的内置函数。
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
>>> def f(x):
... return x * x
...
>>>
>>> r =map(f, [1, 2, 3, 4, 5, 6])
>>> print(r)
<map object at 0x2b9993f1bb00>
>>> list(r)
[1, 4, 9, 16, 25, 36]
>>> list(map(str,[1, 2, 3, 5,7])) --转换成字符串
[‘1‘, ‘2‘, ‘3‘, ‘5‘, ‘7‘]
reduce把一个函数作用在一个序列[x1, x2,x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1,x2), x3), x4)
简单实现下sum的功能
>>> fromfunctools import reduce
>>> def add(x, y):
... return x + y
...
>>> reduce(add,[ 1, 3, 5, 7, 9])
25
再者,把1, 3, 5, 7, 9变成13579
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
...
>>> reduce(fn,[1, 3, 5, 7, 9])
13579
实现int功能,将“13579”转换成13579
>>> from functools import reduce
>>> def strtoint(s):
... def fn(x, y):
... return x * 10 + y
... def chartonum(s):
... return {‘0‘: 0, ‘1‘: 1, ‘2‘: 2, ‘3‘: 3, ‘4‘: 4, ‘5‘: 5, ‘6‘: 6, ‘7‘: 7,‘8‘: 8, ‘9‘: 9}[s] #dict[key],when s=‘0‘then return 0
... return reduce(fn, map(chartonum, s))
...
>>>
>>>
>>> strtoint(‘9102384‘)
9102384
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
>>> def is_odd(n):
... return n % 2 == 1
...
>>>
>>>
>>> list(filter(is_odd, [1, 2, 3,4, 5]))
[1, 3, 5]
注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。
把一个序列中的空字符串删掉
>>> def no_empty(s):
... return s and s.strip()
...
>>>
>>> list(filter(no_empty, [‘a‘,None, ‘ ‘, ‘c‘]))
[‘a‘, ‘c‘]
同理删除字符串中的空格
>>> list(filter(no_empty, (‘ac‘))) --‘a c‘是个iterable
[‘a‘, ‘c‘]
用filter求素数
计算素数的一个方法是埃氏筛法,它的算法理解起来非常简单:
首先,列出从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, ...
不断筛下去,就可以得到所有的素数。
1.这里直接从奇数列开始计算,定义个奇数序列生成器
>>> def _odd_iter():
... n = 1
... while True:
... n = n + 2
... yield n
2.再从奇数列中剔除可除的,定义个不可出函数用于过滤
>>> def _not_divisible(n):
... return lambda x: x % n > 0
3.用filter生成素数产生序列
>>> def prims():
... yield 2
... it = _odd_iter() #最开始的奇数序列3,5,7,9,11,13
... while True:
... n = next(it) #第一次带入3进行不可除函数过滤
... it = filter(_not_divisible(n), it) #形成的新的奇数列:3,5,7,11,13,17,自然第二次带入5进行不可除过滤。
4.尝试生成
>>> for n in prims():
... if n < 100:
... print(n)
... else:
... break
...
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
简单的排序操作
>>> sorted((1, -2, 3, 5))
[-2, 1, 3, 5]
sorted也是个高阶函数
>>> sorted([-18,1,3,-7], key =abs) --按照绝对值大小排序
[1, 3, -7, -18]
字符串的排序—关键在于key
>>> sorted([‘bob‘, ‘about‘, ‘Zoo‘,‘Credit‘])
[‘Credit‘, ‘Zoo‘, ‘about‘, ‘bob‘]
默认按照ASCII的大小比较的
>>> sorted([‘bob‘, ‘about‘, ‘Zoo‘,‘Credit‘], key = str.lower) --转换成小写在比较
[‘about‘, ‘bob‘, ‘Credit‘, ‘Zoo‘]
反向排序
>>> sorted([‘bob‘, ‘about‘, ‘Zoo‘,‘Credit‘], key = str.lower, reverse = True)
[‘Zoo‘, ‘Credit‘, ‘bob‘, ‘about‘]
本文出自 “90SirDB” 博客,请务必保留此出处http://90sirdb.blog.51cto.com/8713279/1820871
Python 函数式编程--高阶函数Map、Reduce、Filter、Sorted
标签:python 函数式编程、map、reduce、filter、sorted
原文地址:http://90sirdb.blog.51cto.com/8713279/1820871