Python基于匹配键/值对减少dict列表

Python基于匹配键/值对减少dict列表,python,merge,key-value,Python,Merge,Key Value,我有一个DICT列表,其中指定了流(从源跳到目的地以及各自的卷)。 现在,我想将这些流拆分为链接(例如(源到卷的跃点,跃点到目标到卷的跃点),并将所有重复的链接汇总在一起 由于我是python新手,我想知道什么是好的方法。我的第一种方法是循环所有流,并在其中的所有链接中嵌套一个循环,然后检查链接是否已经存在 但如果我有数百万的流量,我想这可能会变得非常不有效和缓慢 我的起始数据如下所示: flows = [ { 'source': 1, 'hop': 2,

我有一个DICT列表,其中指定了流(从源跳到目的地以及各自的卷)。 现在,我想将这些流拆分为链接(例如(源到卷的跃点,跃点到目标到卷的跃点),并将所有重复的链接汇总在一起

由于我是python新手,我想知道什么是好的方法。我的第一种方法是循环所有流,并在其中的所有链接中嵌套一个循环,然后检查链接是否已经存在

但如果我有数百万的流量,我想这可能会变得非常不有效和缓慢

我的起始数据如下所示:

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,
    },
]
非常感谢您的帮助!

伪算法:

  • 创建一个空的结果列表/集合/字典
  • 循环数据流列表
  • 将每个流拆分为2个链接
  • 对于这两个链接中的每一个,测试它们是否已经在结果列表中(基于这两个节点)
  • 如果不是:添加。如果是:升级列表中已有卷的卷
  • 伪算法:

  • 创建一个空的结果列表/集合/字典
  • 循环数据流列表
  • 将每个流拆分为2个链接
  • 对于这两个链接中的每一个,测试它们是否已经在结果列表中(基于这两个节点)
  • 如果不是:添加。如果是:升级列表中已有卷的卷

  • 您可以收集到两个不同词典的链接,一个在源和跃点之间,另一个在跃点和目标之间。然后您可以轻松地分别从两个dict创建结果列表。下面使用的是
    dict
    like对象,默认值为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)下运行时间,因此如果您有足够的内存,它应该可以处理数百万个流。

    您可以收集到两个不同字典的链接,一个在源和跃点之间,另一个在跃点和目标之间。然后您可以轻松地分别从两个dict创建结果列表。下面使用的是类似obje的
    dict
    默认值为0的ct:

    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)下运行时间,所以如果你有足够的内存,它应该可以处理数百万个流。

    是你的朋友也是你的朋友这也是我想的。但我的主要问题是,如何有效地完成步骤4。除了每次循环检查结果列表外,我如何检查它?使用
    in
    语句中的
    。例如:
    (1,2)in[(2,3),(1,2)]
    将给出
    True
    。但我不能这样比较,因为元组将包含源代码和tagert,但也包含可能因链接不同而不同的音量(需要求和)。然后切片元组:
    (1,2,98.7)[:2]
    将给出
    (1,2)
    。是否可以编写
    (1,2,50.5)[:2]在[(2,3),(1,2)][:2]
    ?我如何比较(部分)有一个元组部分列表的元组而不循环它们?这也是我想的。但我的主要问题是,如何有效地执行步骤4。除了每次循环遍历结果列表之外,我如何检查它?使用
    in
    语句。例如:
    (1,2)in[(2,3),(1,2)]
    将给出
    True
    。但我不能这样比较它,因为元组将包含源代码和tagert,但也包含可能因链接不同而不同的卷(并且需要求和)。然后将元组切片:
    (1,2,98.7)[:2]
    将给出
    (1,2)
    。是否可以在中编写
    (1,2,50.5)[:2][(2,3),(1,2)][:2]
    ?我如何比较(部分)有元组部分列表的元组没有循环?我喜欢你的方法,但我的音量实际上是一个浮点。所以我想不容易计数…有什么办法解决这个问题吗?@mxzwrnz修复了这个问题,出于某种原因,我读取的输入像是一个字符串,然后我将其转换为int,这样我就可以求和了。删除不必要的内容我喜欢你的方法,但我的音量实际上是一个浮点数。所以我想不容易计数……有什么办法解决这个问题吗?@mxzwrnz修复了这个问题,出于某种原因,我读取的输入就像是一个字符串,然后我将它转换为int,这样我就可以求和了。删除不必要的代码,它就可以正常工作了。