python 高阶函数

本文记录python内建几个函数特性 map、reduce、filter、sorted

map/reduce

map函数有两个参数,第一个参数是一个自定义函数, 第二个参数是序列(list 或者 tuple),返回第二个参数的处理结果(即list或tuple)

1
2
3
4
5
>>> def fun(x):
... return x *x
...
>>> map(fun, range(0, 10))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

列表中的每一个元素会逐一传递到fun函数中并且逐一返回, 当然用循环体也可以达到同样的效果,不过一行代码就能搞定这就够让我使用的欲望了

我们来看一下自定义函数是两个参数的情况

1
2
3
4
5
6
7
8
>>> def add(x, y):
... return x + y
...
>>> map(add, [1, 2, 3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (1 given)
>>>

add函数需要两个参数 所以正确的写法应该是:

1
2
>>> map(add, [1, 2, 3], [1, 2, 3])
[2, 4, 6]

所以在使用map的时候要注意自定义函数的接收参数

reduce函数与map类似不同的是这个自定义函数必须要接收两个参数,并且它的返回值是要累计的, reduce把结果继续和序列的下一个元素执行结果做累积计算
例如:
reduce(f, [1, 2, 3, 4]) 执行顺序是 f(f(f(1, 2), 3), 4)

1
2
>>> reduce(add, [1, 2, 3, 4])
10

当自定义函数需要一个参数的时候

1
2
3
4
>>> reduce(fun, [1, 2, 3, 4])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: fun() takes exactly 1 argument (2 given)

filter

该函数用于过滤序列,和map一样filter()也要接收一个函数和一个序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中
过滤出列表中的所有奇数:

1
2
3
4
5
>>> def is_odd(n):
... return n % 2 == 1
...
>>> filter(is_odd, range(10))
[1, 3, 5, 7, 9]

filter()这个高阶函数的作用关键是自定义函数如何实现一个筛选

sorted

sorted() 函数可对所有可迭代的对象进行排序操作。默认会进行数学意义上的排序

1
2
>>> sorted([3, 5, 2, 1, 4])
[1, 2, 3, 4, 5]

若是想倒序或者列表元素是字符串,这个时候我们就要用到自定义函数了
常规对于两个元素x和y,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1,这样,排序算法就不用关心具体的比较过程,而是根据比较结果直接排序。

1
2
3
4
5
6
7
8
9
10
>>> def cmp(x, y):
... if x > y:
... return 1
... if x < y:
... return -1
... else:
... return 0

>>> sorted([3, 5, 2, 1, 4], cmp)
[1, 2, 3, 4, 5]

倒序:

1
2
3
4
5
6
7
8
9
>>> def cmb(x, y):
... if x > y:
... return -1
... if x < y:
... return 1
... return 0
...
>>> sorted([3, 1, 2, 5, 4], cmb)
[5, 4, 3, 2, 1]

字符串:

默认按照ASCLL的顺序比较

1
2
>>> sorted(['aa', 'CC', 'DD', 'bb'])
['CC', 'DD', 'aa', 'bb']

下面来自定义排序规则,(字母顺序忽略大小写)

1
2
3
4
5
6
7
8
9
10
11
>>> def cmp_ignore_case(x, y):
... x1 = x.upper()
... y1 = y.upper()
... if x1 < y1:
... return -1
... if x1 > y1:
... return 1
... return 0
...
>>> sorted(['aa', 'CC', 'DD', 'bb'], cmp_ignore_case)
['aa', 'bb', 'CC', 'DD']

语法与上面内置函数不同,sorted有四个参数
sorted(iterable, cmp, key, reverse)

参数:

  • iterable – 可迭代对象。
  • cmp – 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
  • key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse – 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
1
2
>>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>> sorted(students, key=lambda s: s[2]) # 按第三个参数排序
1
2
3
4
>>> sorted([3, 1, 2, 5, 4], reverse=True)
[5, 4, 3, 2, 1]
>>> sorted([3, 1, 2, 5, 4], reverse=False)
[1, 2, 3, 4, 5]