将字典列表转换为唯一的字典列表
问题描述:
我一直在努力奋斗几个小时,以解决以下问题,但未取得成功。将字典列表转换为唯一的字典列表
我有一个数据结构,看起来像这样:
[ { 'ROOT': [
{ 'firstElem': 'gc-3/1/0'},
{ 'SecondElem': '5.0.0.1'},
{ 'ThirdElem': '127.3.15.1'},
{ 'index': 16},
{ 'function': 'session'},
{ 'hw': '0.0.0.0'},
{ 'sw': '1.50.1.3'},
{ 'resources': [ { 'cpu-info': [ { 'cpu-peak-load': 1},
{ 'cpu-avg-load': 1}]},
{ 'memory-total': 1},
{ 'memory-used': 2}]},
]},
{ 'ROOT': [
{ 'firstElem': 'gc-4/1/0'},
{ 'SecondElem': '5.0.0.2'},
{ 'ThirdElem': '127.3.4.1'},
{ 'index': 5},
{ 'function': 'stand'},
{ 'hw': '0.0.0.0'},
{ 'sw': '1.50.1.3'},
{ 'resources': [ { 'cpu-info': [ { 'cpu-peak-load': 1},
{ 'cpu-avg-load': 1}]},
{ 'memory-total': 1},
{ 'memory-used': 2}]},
]}
]
我想遍历这个数据结构,并使用相同的名称将所有的字典元素,并创建一个列表来代替。 这是很难解释,我已经创造了什么,我想找一个示例结构:
{
"ROOT": [
{
"firstElem": "gc-3/1/0",
"SecondElem": "5.0.0.1",
"ThirdElem": "128.0.2.19",
"index": "13",
"function": "session",
"hw": "1.11.0.0 ",
"sw": "1.50.0.228 ",
"resources": {
"cpu-info": {
"cpu-peak-load": "1",
"cpu-avg-load": "1",
},
"memory-total": "1",
"memory-used": "2",
},
},
{
"firstElem": "gc-4/1/0",
"SecondElem": "5.0.0.1",
"ThirdElem": "128.0.2.19",
"index": "13",
"function": "session",
"hw": "1.11.0.0 ",
"sw": "1.50.0.228 ",
"resources": {
"cpu-info": {
"cpu-peak-load": "8",
"cpu-avg-load": "1",
},
"memory-total": "1",
"memory-used": "2",
},
}
],
}
我坚持与原始数据结构和不能改变它。任何帮助表示赞赏。 上面提供的结构只是一个例子,因为数据是动态接收的,我不会知道标签名称。所以请不要提供使用特定标签名称的解决方案。
答
这里有一个办法:
>>> from collections import defaultdict
>>> def combine(item):
# Easy return if not a list: element itself
if type(item) != type([]):
return item
# else call recursion
first_ret = [(i.items()[0][0], combine(i.items()[0][1])) for i in item]
# Here we group by same keys if any ('ROOT', for instance)
count_keys = defaultdict(list)
for couple in first_ret:
count_keys[couple[0]].append(couple[1])
return dict((k, v if len(v) > 1 else v[0]) for k, v in count_keys.iteritems())
我只好组ROOT
节点,但它似乎是工作:
>>> pprint(combine(l))
{'ROOT': [{'SecondElem': '5.0.0.1',
'ThirdElem': '127.3.15.1',
'firstElem': 'gc-3/1/0',
'function': 'session',
'hw': '0.0.0.0',
'index': 16,
'resources': {'cpu-info': {'cpu-avg-load': 1,
'cpu-peak-load': 1},
'memory-total': 1,
'memory-used': 2},
'sw': '1.50.1.3'},
{'SecondElem': '5.0.0.2',
'ThirdElem': '127.3.4.1',
'firstElem': 'gc-4/1/0',
'function': 'stand',
'hw': '0.0.0.0',
'index': 5,
'resources': {'cpu-info': {'cpu-avg-load': 1,
'cpu-peak-load': 1},
'memory-total': 1,
'memory-used': 2},
'sw': '1.50.1.3'}]}
>>>
答
让我们试试这个:
r = {}
def lst2dct(lst):
return (lst if not isinstance(lst, list) else
{k: lst2dct(v) for e in lst for k, v in e.items()})
for e in source:
key, val = e.items()[0]
r.setdefault(key, []).append(lst2dct(val))
答
它有点哈克,但你可以尝试:
data = [ { 'ROOT': [
{ 'firstElem': 'gc-3/1/0'},
{ 'SecondElem': '5.0.0.1'},
{ 'ThirdElem': '127.3.15.1'},
{ 'index': 16},
{ 'function': 'session'},
{ 'hw': '0.0.0.0'},
{ 'sw': '1.50.1.3'},
{ 'resources': [ { 'cpu-info': [ { 'cpu-peak-load': 1},
{ 'cpu-avg-load': 1}]},
{ 'memory-total': 1},
{ 'memory-used': 2}]},
]},
{ 'ROOT': [
{ 'firstElem': 'gc-4/1/0'},
{ 'SecondElem': '5.0.0.2'},
{ 'ThirdElem': '127.3.4.1'},
{ 'index': 5},
{ 'function': 'stand'},
{ 'hw': '0.0.0.0'},
{ 'sw': '1.50.1.3'},
{ 'resources': [ { 'cpu-info': [ { 'cpu-peak-load': 1},
{ 'cpu-avg-load': 1}]},
{ 'memory-total': 1},
{ 'memory-used': 2}]},
]}
]
root_list = [
]
final_data = {
'ROOT' : root_list
}
for dict in data:
if dict['ROOT'] not in final_data['ROOT']:
final_data['ROOT'].append(dict['ROOT'])
+0
请参阅已编辑的问题,我不能使用特定的标签名称,这仅仅是一个示例。 – theAlse 2013-02-12 17:26:06
答
我只是做了一些在这里和那里的东西的解释,并拿出了这一点:
>>> i = [...] # your data
>>> rdict = {}
>>> for di in i:
for root in di:
if root not in rdict:
rdict[root] = [di[root]]
else:
rdict[root] += [di[root]]
rdict
字典是你所需要的类型,应该多升工作派。
这个功能版本:
def common_dict(list_of_dicts):
i = list_of_dicts # less typing
rdict = {}
for di in i:
for root in di:
if root not in rdict:
rdict[root] = [di[root]]
else:
rdict[root] += [di[root]]
return rdict
用真实代码测试,它不是工作,它似乎只采取一个根元素,第二个不知何故被丢弃! – theAlse 2013-02-13 09:28:21
@theAlse:在某处发布实际数据(例如gist.github.com) – georg 2013-02-13 09:46:37