下面介绍如何使用复杂的生成器表达式转换数据类型,以及如何把复杂函数应用于生成器创建的单个值。
这些非生成器函数是“标量的”,因为它们处理的是单个标量值。为了处理集合数据,需要把标量函数嵌入生成器表达式中。
继续前面的例子,首先创建haversine函数,然后使用生成器表达式将标量的haversine函数应用于从KML文件中提取的数值。
haversine函数的具体实现如下:
这个实现比较简单,在网上搜索一下,找到代码并复制过来即可。这里给起点、终点和返回值添加了类型标示,显式类型声明Point = Tuple[float, float]使得mypy工具可以正确地使用函数。
下面的代码演示了如何使用前面定义好的函数处理KML文件中的数据,并计算出距离序列:
关键部分是赋给trip变量的生成器表达式。我们用起点、终点以及两点间的距离组成三元组,其中起点和终点来自legs()函数,用它来处理从KML文件中提取的经纬度数值对转换而来的浮点数据。
计算结果如下所示:
这样就简洁地定义了每个处理步骤。整个处理过程由函数和生成器表达式组成,总体而言也很简洁。
当然,这里得到的输出数据还需要进一步处理,比如首先需要用字符串的format()方法把输出数据整理得易读一些。
更重要的是,需要从数据中提取一些累积值,即对已有数据进行归约。比如可以提取数据的最大纬度值和最小纬度值,从而得到一条路线的最南点和最北点。或者通过归约数据,找到路径段中最长的距离,或者所有距离的和。
使用Python处理数据时有个问题:trip变量只能使用一次,无法对其进行多次归约,而itertools.tee()函数能够多次使用可迭代对象,毕竟每次归约都要重新读取并解析KML文件,成本太高了。
将中间计算结果实例化可以提高计算效率,稍后详述并介绍如何对已有数据进行多次归约。