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

python—将字典列表拆分为多个字典列表,而不进行分组,python,dictionary,itertools,Python,Dictionary,Itertools,我正在尝试将字典列表按两个键/值拆分为多个列表。字典的原始列表是从一个返回数据速度较慢的应用程序(第三方)中提取出来的,因此我避免了多次调用,现在我可以在一次查询中获得所需的所有数据。但是,我现在需要将这些数据拆分为匹配节点ID和名称的组,同时维护原始数据 样本数据: [{'NodeID': 1563, 'Name': 'GigabitEthernet1/1/1', 'InAveragebps': 0.03555526, 'OutAveragebps': 64.50593, 'DateTime'

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

样本数据:

[{'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'
}]
因此,put将有两个这样的列表:

[{'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、collections:

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)

考虑到这看起来是多么简单,我目前还没有取得任何进展。

您可以使用
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'}]]
这可能是返回列表结果的一种迂回方式,但最终您需要进行某种类型的成员资格测试(或者,在本例中,更像是查找),而字典首先非常适合这样做

在调用
list()
之前,
interface\u data
是一个嵌套字典;它的键是(NodeID,Name)的2元组,它的值是字典本身

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

您可以使用
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'}]]
这可能是返回列表结果的一种迂回方式,但最终您需要进行某种类型的成员资格测试(或者,在本例中,更像是查找),而字典首先非常适合这样做

在调用
list()
之前,
interface\u data
是一个嵌套字典;它的键是(NodeID,Name)的2元组,它的值是字典本身

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

对于这个问题,
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
排序,则必须应用
排序

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

对于这个问题,
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
排序,则必须应用
排序

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

您使用
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'}]]

您使用
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'}]]


您的代码产生了什么结果/错误?您会考虑使用嵌套的DICT吗?例如,NodeID将是易于查找的键,其值将是具有该ID的元素列表。“我目前没有进展”不是问题陈述。当然,你有一些特殊的症状,你想分享和讨论吗?当你在它的时候,请正确地缩进你的第二个片段。你的代码产生了什么结果/错误?你会考虑使用嵌套的DICT来代替吗?例如,NodeID将是易于查找的键,其值将是具有该ID的元素列表。“我目前没有进展”不是问题陈述。当然,您有一些想与大家分享和讨论的“一事无成”的具体症状吗?当您这样做时,请正确缩进您的第二个代码段。根据数据的填充方式,可能需要在
groupby
无序数据
groupby
失去兴趣之前进行排序,defaultdict是一种方式。根据数据的填充方式,在无序数据的情况下,
groupby
可能需要排序,而defaultdict是一种方式。因此,使用集合我可以选择特定的列表组?是的,如果这是您的最终目的,也许您希望保留为嵌套的defaultdict?id,您希望能够仅选择列表1(使用id和接口)或任意n列表,具体取决于它们。你的样品里有什么?当我当前在shell中运行此命令时,我得到了TypeError:列表索引必须是整数或片,而不是tuple
s
是示例数据,与您在问题
interface_data[(1563,'gigabiteEthernet1/1/1')中的数据完全相同
where
interface\u data
是默认目录,因此使用集合我可以选择特定的列表组?是的,如果这是您的最终目的,也许您希望保留为嵌套的默认目录?id希望能够仅选择列表1(使用id和接口)或任意n列表,具体取决于它们。你的样品里有什么?当我当前在shell中运行此命令时,我得到了TypeError:列表索引必须是整数或切片,而不是tuple
s
是示例数据,与您在问题
interface\u data[(1563,'gigabiteEthernet1/1/1')]中的数据完全相同
其中
interface\u data
是默认的dict