python-将字典列表拆分为多个字典列表,而不进行分组

时间:2018-08-06 16:06:51

标签: python dictionary itertools

我正在尝试将字典列表按两个键/值分成多个列表。字典的原始列表是从返回数据速度较慢的应用程序(第3方)中提取的,因此我避免了多次调用,现在可以在一个查询中获取所需的所有数据。但是,我现在需要将这些数据分成与NodeID和名称匹配的组,同时保持原始数据

样本数据:

[{'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.03555526, 'OutAveragebps': 64.50593, 'DateTime': '2018-05-29T01:10:00.0000000'
},
{'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.04555526, 'OutAveragebps': 6456.50593, 'DateTime': '2018-05-29T01:11:00.0000000'
},
{'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03554479, 'OutAveragebps': 64.7012558, 'DateTime': '2018-05-16T01:01:00.0000000'
},
{'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03555063, 'OutAveragebps': 64.62538, 'DateTime': '2018-05-17T01:011:00.0000000'
}]

所以看跌期权将有两个清单:

[{'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.03555526, 'OutAveragebps': 64.50593, 'DateTime': '2018-05-29T01:10:00.0000000'
},
{'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.04555526, 'OutAveragebps': 6456.50593, 'DateTime': '2018-05-29T01:11:00.0000000'
}],[
{'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03554479, 'OutAveragebps': 64.7012558, 'DateTime': '2018-05-16T01:01:00.0000000'
},
{'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03555063, 'OutAveragebps': 64.62538, 'DateTime': '2018-05-17T01:011:00.0000000'
}]

我尝试使用itertools,集合:

from operator import itemgetter
from itertools import groupby

interface_data = []
grouper = itemgetter("NodeID", "Name")
for key,v in groupby(sorted(results, key = grouper), grouper):
    temp_dict = dict(zip(["NodeID", "Name"], key))
    interface_data.append(temp_dict) 

收藏

from collections import defaultdict
interface_data = defaultdict(list)
for i in results:
     interface_data[(i['NodeID'],i['InterfaceName'])].append(i)

考虑到这看起来多么简单,我现在什么都没得到,这令人沮丧。

3 个答案:

答案 0 :(得分:4)

您可以使用defaultdict创建一个嵌套字典,然后对其值调用list()

>>> from collections import defaultdict
>>> interface_data = defaultdict(list)
>>> for i in s:
...     key = i['NodeID'], i['Name']
...     interface_data[key].append(i)

>>> list(interface_data.values())
[[{'NodeID': 1563,
   'Name': 'GigabitEthernet1/1/1',
   'InAveragebps': 0.03555526,
   'OutAveragebps': 64.50593,
   'DateTime': '2018-05-29T01:10:00.0000000'},
  {'NodeID': 1563,
   'Name': 'GigabitEthernet1/1/1',
   'InAveragebps': 0.04555526,
   'OutAveragebps': 6456.50593,
   'DateTime': '2018-05-29T01:11:00.0000000'}],
 [{'NodeID': 1788,
   'Name': 'GigabitEthernet2/1/2',
   'InAveragebps': 0.03554479,
   'OutAveragebps': 64.7012558,
   'DateTime': '2018-05-16T01:01:00.0000000'},
  {'NodeID': 1788,
   'Name': 'GigabitEthernet2/1/2',
   'InAveragebps': 0.03555063,
   'OutAveragebps': 64.62538,
   'DateTime': '2018-05-17T01:011:00.0000000'}]]

返回列表结果可能有点round回,但是最终您想要进行某种类型的成员资格测试(或者,在这种情况下,更像是查找),并且字典很适合-首先适合它。

在调用list()之前,interface_data是一个嵌套字典;它的键是2个元组(节点ID,名称),其值是字典本身。

>>> interface_data.keys()
dict_keys([(1563, 'GigabitEthernet1/1/1'), (1788, 'GigabitEthernet2/1/2')])

答案 1 :(得分:1)

对于这个问题,itertools.groupby非常简单,因为只有'NodeId'被用作分组密钥:

import itertools
d = [{'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.03555526, 'OutAveragebps': 64.50593, 'DateTime': '2018-05-29T01:10:00.0000000'}, {'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.04555526, 'OutAveragebps': 6456.50593, 'DateTime': '2018-05-29T01:11:00.0000000'}, {'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03554479, 'OutAveragebps': 64.7012558, 'DateTime': '2018-05-16T01:01:00.0000000'}, {'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03555063, 'OutAveragebps': 64.62538, 'DateTime': '2018-05-17T01:011:00.0000000'}]
final_result = [list(b) for _, b in itertools.groupby(d, key=lambda x:x['NodeID'])]

输出:

[[{'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.03555526, 'OutAveragebps': 64.50593, 'DateTime': '2018-05-29T01:10:00.0000000'}, {'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.04555526, 'OutAveragebps': 6456.50593, 'DateTime': '2018-05-29T01:11:00.0000000'}], [{'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03554479, 'OutAveragebps': 64.7012558, 'DateTime': '2018-05-16T01:01:00.0000000'}, {'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03555063, 'OutAveragebps': 64.62538, 'DateTime': '2018-05-17T01:011:00.0000000'}]]

编辑:

如果不能保证您的数据按id进行排序,则必须应用sorted

final_result = [list(b) for _, b in itertools.groupby(sorted(d, key=lambda x:x['NodeID']), key=lambda x:x['NodeID'])]

答案 2 :(得分:0)

您使用itertools.groupby的解决方案已经非常接近,但是除了附加key之外,您还应该在将v转换为列表后附加from operator import itemgetter from itertools import groupby interface_data = [] grouper = itemgetter("NodeID", "Name") for _, v in groupby(sorted(results, key = grouper), grouper): interface_data.append(list(v)) print(interface_data)

[[{'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.03555526, 'OutAveragebps': 64.50593, 'DateTime': '2018-05-29T01:10:00.0000000'}, {'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.04555526, 'OutAveragebps': 6456.50593, 'DateTime': '2018-05-29T01:11:00.0000000'}], [{'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03554479, 'OutAveragebps': 64.7012558, 'DateTime': '2018-05-16T01:01:00.0000000'}, {'NodeID': 1788, 'Name': 'GigabitEthernet2/1/2', 'InAveragebps': 0.03555063, 'OutAveragebps': 64.62538, 'DateTime': '2018-05-17T01:011:00.0000000'}]]

这将输出:

input=|3E 00|redcar|0D|.