测试开发之Python核心笔记(12): 匿名函数与高阶函数

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

为了忽略大小写,将所有的字符全部转成小写进行比较。

猜你喜欢

转载自blog.csdn.net/liuchunming033/article/details/107896143