Python 编写通用的group-by归约,将原始数据分区后,就可以对每个分区中的数据执行多种归约操作了,例如提取出每个路径段中最靠北的起点。
首先引入如下辅助函数来拆解元组:
start = lambda s, e, d: s
end = lambda s, e, d: e
dist = lambda s, e, d: d
latitude = lambda lat, lon: lat
longitude = lambda lat, lon: lon
每个辅助函数的输入值是一个元组,通过*
运算符将元组中的每个元素拆解为匿名函数的多个输入参数。当把元组的元素拆解为s
、e
和p
这3个参数后,就可以方便地按名称得到返回值了。这种方法比tuple_arg[2]
方式更明了。
如下所示使用这些辅助参数:
>>> point = ((35.505665, -76.653664), (35.508335, -76.654999), 0.1731)
>>> start(*point)
(35.505665, -76.653664)
>>> end(*point)
(35.508335, -76.654999)
>>> dist(*point)
0.1731
>>> latitude(*start(*point))
35.505665
输入数据是嵌套三元组,按照下标依次为起点、终点和距离。利用上面定义的辅助函数,就能抽取不同的元素。
基于这些辅助函数,提取每个箱子中起点最靠北的路径段的实现如下所示:
for distance in sorted(by_distance):
print(
distance,
max(by_distance[distance],
key=lambda pt: latitude(*start(*pt)))
)
首先按距离将各个路径段分组,用这些路径段作为max()
函数的输入,这个函数的key
参数是一个从路径段中提取出起点纬度的匿名函数。
返回结果是每个箱子中起点最靠北的路径段列表,如下所示:
0.0 ((35.505665, -76.653664), (35.508335, -76.654999), 0.1731)
5.0 ((38.845501, -76.537331), (38.992832, -76.451332), 9.7151)
10.0 ((36.444168, -76.3265), (36.297501, -76.217834), 10.2537)
...
125.0 ((27.154167, -80.195663), (29.195168, -81.002998), 129.7748)