Python 根据匹配 key/value 对减少字典列表

Python Reduce List of Dicts based on matching key/value pairs

我有一个指定流的字典列表(从源跳到目的地及其各自的音量)。 现在我想将这些流量拆分为 link(例如(源到流量跳转,跳到目的地流量)并通过汇总它们的流量将所有重复的 link 合并在一起。

因为我是 python 的新手,所以我想知道什么是好的方法。我的第一种方法是遍历所有流并在内部嵌套一个遍历所有 link 的循环,并检查 link 是否已经存在。

但如果我有数百万个流,我想这可能会变得非常低效和缓慢。

我的起始数据是这样的:

flows = [
    {
        'source': 1,
        'hop': 2,
        'destination': 3,
        'volume': 100,
    },{
        'source': 1,
        'hop': 2,
        'destination': 4,
        'volume': 50,
    },{
        'source': 2,
        'hop': 2,
        'destination': 4,
        'volume': 200,
    },
]

我的结果应该是:

links = [
    {
        'source': 1,
        'hop': 2,
        'volume': 150,
    },{
        'hop': 2,
        'destination': 3,
        'volume': 100,
    },{
        'hop': 2,
        'destination': 4,
        'volume': 250,
    },{
        'source': 2,
        'hop': 2,
        'volume': 200,
    },
]

非常感谢您的帮助!

伪算法:

  1. 创建一个空结果 list/set/dictionary
  2. 循环流列表
  3. 将每个流拆分为 2 个链接
  4. 对于这 2 个链接中的每一个,测试它们是否已经在结果列表中(基于 2 个节点)。
  5. 如果没有:添加它们。如果是:升级列表中已有的音量。

您可以收集指向两个不同词典的链接,一个在源和跃点之间,另一个在跃点和目标之间。然后您可以轻松地从两个字典中单独创建结果列表。 Counter 下方使用了 dict 类似默认值为 0 的对象:

import pprint
from collections import Counter

flows = [
    {
        'source': 1,
        'hop': 2,
        'destination': 3,
        'volume': 100.5,
    },{
        'source': 1,
        'hop': 2,
        'destination': 4,
        'volume': 50,
    },{
        'source': 2,
        'hop': 2,
        'destination': 4,
        'volume': 200.7,
    },
]

sources = Counter()
hops = Counter()

for f in flows:
    sources[f['source'], f['hop']] += f['volume']
    hops[f['hop'], f['destination']] += f['volume']

res = [{'source': source, 'hop': hop, 'volume': vol} for (source, hop), vol in sources.items()]
res.extend([{'hop': hop, 'destination': dest, 'volume': vol} for (hop, dest), vol in hops.items()])
pprint.pprint(res)

输出:

[{'hop': 2, 'source': 1, 'volume': 150.5},
 {'hop': 2, 'source': 2, 'volume': 200.7},
 {'destination': 3, 'hop': 2, 'volume': 100.5},
 {'destination': 4, 'hop': 2, 'volume': 250.7}]

以上 运行 需要 O(n) 时间,因此如果您有足够的内存,它应该可以处理数百万个流。