Python 函数式编程--高阶函数Map、Reduce、Filter、Sorted,,1.1高阶函数变量可


1.1高阶函数

变量可指向函数

>>> 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

1.1.1Map/Reduce

Map和Reduce函数都是python的内置函数。

1.1.1.1Map

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‘]

1.1.1.2Reduce

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

1.1.2Filter

和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

1.1.3Sorted

简单的排序操作

>>> 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

评论关闭