Python 拆包和映射数据,当使用类似于(f(x) for x, y in C)
这样的结构时,我们使用for
语句中的多重赋值拆开一个元组,并将一个函数应用于其中一部分数据。整体上这是一个映射。这是Python常用的改变结构和应用函数的优化方法。
继续使用第4章中的旅行数据。下面是一个拆包并映射的具体实现。
该高阶函数使用下面的转换函数处理原始数据。
有了转换函数,就可以提取距离数据,再进行转换了,如下所示:
处理结果是一系列浮点数,如下所示:
从convert()
函数的for
语句不难看出,这个函数只适用于“起点-终点-距离”格式的旅行数据。
可以进一步抽象这类“拆包-映射”设计模式,整个过程稍复杂。首先需要定义通用分解函数,如下所示:
要表达f(sel2(s_e_d)) for s_e_d in trip
,就要用到复合函数。我们把一个类似于to_miles()
的函数和一个类似于sel2()
的选择器组合在一起。在Python中,可以用匿名函数把函数组合在一起,如下所示:
这样就得到了一个更长,但更通用的实现,如下所示:
这个版本更具通用性,不过用处似乎不太大。
对于上述convert()
高阶函数,需要特别注意的是,它使用函数作为参数,并返回生成器函数作为结果。convert()
函数不是生成器函数,不会生成任何值,它的返回值是一个生成器表达式,需要对其求值才能得到具体的计算结果。我们使用Iterator[float]
来强调返回结果是迭代器,也就是
Python生成器函数的子类。
在这个设计模式中,可以用多重过滤代替映射,实现方法是在返回的生成器表达式中,用if
从句实现过滤功能。
映射和过滤结合可以生成更复杂的函数。创建复杂的函数来缩短处理过程似乎是个好主意,但实际情况并非总是如此。复杂函数的性能往往不如嵌套的map()
函数和filter()
函数。总体而言,只有在函数通过封装概念来降低软件开发复杂度的情况下,才考虑使用复杂函数。