按 Python 中的复合键分组

Grouping by composite key in Python

我有一个这样的 CSV 文件:

route|id|alias|longitude|latitude
A|1|first|-33.51808226|-70.58256582
A|1|first|-33.52850414|-70.57645648
B|2|second|-33.51952529|-70.58043875
B|2|second|-33.53452223|-70.58343824

每条路线都有一个 id 和一个 alias,它们对于相同的 route 总是相同的。此外,每个 route 都有一组 points,每个都由 longitudelatitude 组成。我正在尝试按 routepoints 进行分组,但我想生成文件的每个字段。

当我使用 itertools groupbyroute 分组时,我只能得到 routepoints:

with open(self.datafile, "r") as f:
        reader = csv.DictReader(f, delimiter='|')
        # Group data using 'route' as key
        for route, points in groupby(reader, lambda p: p['route']):
            points = list(points)
            points = [
                {
                    'longitude': p['longitude'],
                    'latitude': p['latitude']
                } for p in points
            ]
            yield {
                "_source": {
                    "route": route,
                    "points": points
                }
            }

我尝试了不同的方法来获取 idalias route(比如使用 route['id']p['id'] 来获取 id 或在现有的之外使用另一个),但其中 none 有效。

有没有办法在使用 groupby 时使用组合键?或者更简单的解决方案?

我希望能够产生这个:

yield {
                "_source": {
                    "route": route,
                    "id": id,
                    "alias": alias,
                    "points": points
                }
            }

如果您 return 来自 key 函数的元组,您可以一次 groupby 多个字段。

您可以使用 operator.itemgetter。 for 循环看起来像:

for (route, id, alias), points in groupby(reader, key=operator.itemgetter('route', 'id', 'alias')):

您确实可以 groupby 使用复合键:

# Group data using 'route', 'id', 'alias' as key
for route_id_alias, values in itertools.groupby(reader, lambda p: (p['route'], p['id'], p['alias'])):
    points = [
        {
            'longitude': p['longitude'],
            'latitude': p['latitude'],
        } for p in values
    ]
    print( {
        "_source": {
            "route": route_id_alias[0],
            "id": route_id_alias[1],
            "alias": route_id_alias[2],
            "points": points,
        }
    })

您只需要在生成结果时通过索引访问您的密钥。

Try it online!