Python基于匹配键/值对减少dict列表
我有一个DICT列表,其中指定了流(从源跳到目的地以及各自的卷)。 现在,我想将这些流拆分为链接(例如(源到卷的跃点,跃点到目标到卷的跃点),并将所有重复的链接汇总在一起 由于我是python新手,我想知道什么是好的方法。我的第一种方法是循环所有流,并在其中的所有链接中嵌套一个循环,然后检查链接是否已经存在 但如果我有数百万的流量,我想这可能会变得非常不有效和缓慢 我的起始数据如下所示:Python基于匹配键/值对减少dict列表,python,merge,key-value,Python,Merge,Key Value,我有一个DICT列表,其中指定了流(从源跳到目的地以及各自的卷)。 现在,我想将这些流拆分为链接(例如(源到卷的跃点,跃点到目标到卷的跃点),并将所有重复的链接汇总在一起 由于我是python新手,我想知道什么是好的方法。我的第一种方法是循环所有流,并在其中的所有链接中嵌套一个循环,然后检查链接是否已经存在 但如果我有数百万的流量,我想这可能会变得非常不有效和缓慢 我的起始数据如下所示: flows = [ { 'source': 1, 'hop': 2,
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,
},
]
非常感谢您的帮助!伪算法:
您可以收集到两个不同词典的链接,一个在源和跃点之间,另一个在跃点和目标之间。然后您可以轻松地分别从两个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,这样我就可以求和了。删除不必要的代码,它就可以正常工作了。