12.1 定义匿名函数
匿名函数应用非常广泛。常用在不方便定义常规函数的地方,作为参数的值来使用。
- lambda开头 接着参数列表,接着冒号,后面是表达式,函数返回值就是表达式的值。
lambda x: x**2
- 可以赋值给变量:
>>> square = lambda x: x**2
>>> square(3)
9
12.2 匿名函数的用处
- 用在常规函数 def 不能用的地方,比如,用在列表内部
[(lambda x: x*x)(x) for x in range(10)] # 更简单的方式 [x*x for i in range(10)], 这里range(10)是一个包含0~9的迭代器
- lambda 可以被用作某些函数的参数:
l = [(1, 20), (3, 0), (9, 10), (2, -1)]
l.sort(key=lambda x: x[1]) # 按列表中元组的第二个元素排序
s = [1, 2, 3, 4, 5]
new_list = map(lambda x: x * 2, s) # 列表元素的二倍
- 函数特别简短,而且只用一次的场景:
squared = map(lambda x: x**2, [1, 2, 3, 4, 5]) # 对列表中的元素求平方
l = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, l) # 1*2*3*4*5 = 120
a="function using arguments"
max(a,key=lambda x: a.count(x), default=1) # 求出个数最多的元素,a为None时,返回default
12.3 高阶函数
函数接收另一个函数作为参数,这种函数称为高阶函数。
12.3.1 map
map函数的官方介绍:
class map(object):
"""
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.
"""
def __init__(self, func, *iterables): # real signature unknown; restored from __doc__
pass
在python3中map被封装成了一个类,在它的描述文档中,说明了使用方法是map(func, *iterables) --> map object
,功能是将func作用于 iterables 中的每一项,最后返回的结果就是一个map对象。map对象可以通过list转成列表。
A = map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 计算列表各个元素的平方,返回迭代器,这里给map传递的是一个lambda匿名函数
print(list(A)) # 通过map转换成列表
B = map(lambda x: x[0].upper() + x[1:].lower(), ['chun', 'MinG', 'LIU']) # 按照首字母大写,后续字母小写的规则
print(list(B))
从官方文档看到map的iterables参数前面有一个星号,表示可以传递多个可迭代对象进去。可以并行的对多个迭代对象进行处理。
比如求两个列表的平方和组成的新列表,比如l1=[1,2,3],l2=[4,5,6]。生成新列表是对应元素的平方和。
l1 = [1, 2, 3]
l2 = [4, 5, 6]
C = map(lambda x, y: x * x + y * y, l1, l2)
print(list(C))
多个iterables对象的长度不一致也没有关系。
再比如,同时满足第一个列表的元素为奇数,第二个列表对应位置的元素为偶数时。为True,否则为False。生成新的列表。
D = map(lambda x,y: x%2==1 and y%2==0, [1,3,2,4,1],[3,2,1,2])
print(list(D))
12.3.2 filter
filter函数的源码如下:
class filter(object):
"""
filter(function or None, iterable) --> filter object
Return an iterator yielding those items of iterable for which function(item)
is true. If function is None, return the items that are true.
"""
def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass
def __init__(self, function_or_None, iterable): # real signature unknown; restored from __doc__
pass
filter函数用来对可迭代对象进行过滤,将可迭代对象的元素逐个作用于function函数,当funciton函数返回True时,将其过滤出来,最终返回一个迭代器。
l = [1, 2, 3, 4, 5]
new_list = filter(lambda x: x % 2 == 0, l) #过滤出偶数
12.3.3 reduce
Python3使用reduce函数要先导入:from functools import reduce
。reduce的官方介绍:
def reduce(function, sequence, initial=None): # real signature unknown; restored from __doc__
"""
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
"""
pass
reduce对原sequence进行处理,两两运算最后形成一个值。上面的官网还举例一个例子,计算1+2+3+4+5的和。
from functools import reduce
value = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(value)
reduce函数还有一个可选的initial参数,当sequence不存在时,reduce返回initial。当sequence存在时,initial放到sequence首部参与计算。例如:
from functools import reduce
value = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5], 100)
print(value) # 返回115
再看一个计算列表中元素乘积的例子:
l = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, l) # 1*2*3*4*5 = 12
12.3.5 sorted
对于数值的排序,我们使用值进行比较,根据大小进行排序即可。但是对于字符串或者类对象或者字典进行排序时,就需要我们自己定义排序的规则了。sorted函数接收一个排序规则的函数,根据排序规则来进行排序。看一下官网对sorted描述:
sorted(iterable, /, *, key=None, reverse=False)
Return a new list containing all items from the iterable in ascending order.A custom key function can be supplied to customize the sort order, and the
reverse flag can be set to request the result in descending order.
还记得如何阅读官方文档中关于函数的描述吗?前面10.4小节介绍过。sorted函数形参列表中有一个 /
,它表示 /
前的参数只能是位置参数,不能是关键字参数,符号 *
表示,后面的形参只能为关键字参数,不能为位置参数。sorted的第一参数是可迭代对象,经过sorted函数之后,可迭代对象会根据key定义的函数进行排序。举个例子:
对字符串列表,忽略大小写按照字母序排序,也就是第一个字母相同时,按照下一个字母序排序。
print(sorted(['ming', 'liu', 'Chun', 'chong' ], key=str.lower)) # ['chong', 'Chun', 'liu', 'ming']
为了忽略大小写,将所有的字符全部转成小写进行比较。