我有一个来自yaml的dict转换列表,但是如何将它们合并为一个新的?
我想合并这个;
ip_service_list = [{'192.168.15.90': {'process': {'nginx': 1}}}, {'192.168.15.90': {'process': {'varnish': 1}}}, {'192.168.15.91': {'process': {'tomcat': 1}}}]
成为这个;
{
'192.168.15.90':
{'process': {'nginx': 1,'varnish': 1}}},
'192.168.15.91':
{'process': {'tomcat': 1}
}
答案 0 :(得分:3)
from collections import defaultdict
# the structure we try to fill is in the lambda
d = defaultdict(lambda:{'process' : {}})
for row in s:
# just one iteration, aka ip = next(iter(row))
for ip in row:
d[ip]['process'].update(row[ip]['process'])
print d
答案 1 :(得分:2)
dictlist = [{'192.168.15.90': {'process': {'master': 1}}},
{'192.168.15.90': {'process': {'varnish': 1}}},
{'192.168.15.91': {'process': {'tomcat': 1}}}]
dd = {
'192.168.15.90':
{'process': {'master': 1,'varnish': 1}},
'192.168.15.91':
{'process': {'tomcat': 1}
}}
new = {}
# for each dict in the list
for dct in dictlist:
# get the ip address
ip, = dct
# if the ip address is already in the new dict
if ip in new:
# copy in the process info
new[ip]['process'].update(dct[ip]['process'])
# if the ip address isn't in the new dict yet
else:
# add the ip address and its info to the new dict
new.update(dct)
print dd == new # True!
答案 2 :(得分:1)
如果你有平坦的词典,你可以这样做:
reduce(lambda a, b: dict(a, **b), list_of_dicts)
答案 3 :(得分:0)
new = {}
old = [{'192.168.15.90': {'process': {'master': 1}}}, {'192.168.15.90': {'process': {'varnish': 1}}}, {'192.168.15.91': {'process': {'tomcat': 1}}}]
def recursive_update(target, source):
for k, v in source.items():
if type(v) == dict:
new = target.setdefault(k,{})
recursive_update(new, v)
else:
target[k] = v
for d in old:
recursive_update(new,d)
print(repr(new))
结果:
>> {'192.168.15.91': {'process': {'tomcat': 1}}, '192.168.15.90': {'process': {'varnish': 1, 'master': 1}}}
答案 4 :(得分:0)
可能是使用itertools.groupby的好机会:
_list = [{'192.168.15.90': {'process': {'master': 1}}}, {'192.168.15.90': {'process': {'varnish': 1}}}, {'192.168.15.91': {'process': {'tomcat': 1}}}]
def get_ip(_d):
assert(len(_d.keys())==1)
return _d.keys()[0]
_list.sort(key=get_ip)
from itertools import groupby
result = {}
for k,g in groupby(_list,key=get_ip):
sub_result = {}
for i in g:
v = i[k]
_process = v['process']
assert(len(_process.items())==1)
_process_key,_process_value = _process.items()[0]
assert(_process_key not in sub_result)
sub_result[_process_key] = _process_value
result[k] = {'process': sub_result}
import pprint
pprint.pprint(result)
"""
>>>
{'192.168.15.90': {'process': {'master': 1, 'varnish': 1}},
'192.168.15.91': {'process': {'tomcat': 1}}}
"""