我有一个包含许多嵌套字典的列表,每个字典代表一个 Windows 操作系统,如下所示:
windows1 = {"version": "windows 10",
"installed apps": {"chrome": "installed",
"python": {"python version": "2.7",
"folder": "c:\python27"},
"minecraft": "not installed"}}
windows2 = {"version": "windows XP",
"installed apps": {"chrome": "not installed",
"python": {"python version": "not installed",
"folder": "c:\python27"},
"minecraft": "not installed"}}
我的目标是创建一个最终的嵌套字典,以存储有关列表的统计信息,如下所示:
stats_dic = {"version": {"windows 10": 20,
"windows 7": 4,
"windows XP": 11},
"installed apps": {"chrome": {"installed": 12,
"not installed": 6},
"python": {"python version": {"2.7": 4, "3.6": 8, "3.7": 2},
"minecraft": {"installed": 15,
"not installed": 2}}}
如您所见,我试图获取列表中每个 windows dict 中的所有值(python 文件夹除外),将它们作为最终嵌套统计 dict 中的键。这些键的值将是它们的计数器,并且它们必须保持与以前相同的嵌套方式。
经过一些阅读后,我明白这可以在递归函数中完成,并且我尝试了几个函数但都没有成功。我得到的最接近的(没有照顾 python 文件夹)是:
stats_dic = {}
windows_list = [s1, s2.....]
def update_recursive(s,d):
for k, v in s.iteritems():
if isinstance(v, dict):
update_recursive(v, d)
else:
if v in d.keys():
d[v] += 1
else:
d.update({v: 1})
return d
for window in windows_list():
stats_dic = update_recursive(window, stats_dic)
哪个给了我 windows1 和 windows2:
{'windows XP': 1, 'windows 10': 1, '2.7': 1, 'not installed': 2, 'c:\\python27': 1, 'installed': 1}
如您所见,它没有保持嵌套形式,并且还混合了相同的值(chrome 和 mincraft '未安装') 我尝试过的所有其他方法要么没有增加计数器,要么只保留一个深度的嵌套表单。我知道我没有接近,但我错过了什么?
答案 0 :(得分:2)
这是一个递归函数,它会做我认为你想要它做的事情。
from pprint import pp # Skip if you're not running Python >= 3.8
def combiner(inp, d=None):
if d == None:
d = {}
for key, value in inp.items():
if isinstance(value, str):
x = d.setdefault(key, {})
x.setdefault(value, 0)
x[value] += 1
elif isinstance(value, dict):
x = d.setdefault(key, {})
combiner(value, x)
else:
raise TypeError("Unexpected type '{}' for 'value'".format(type(value)))
return d
windows1 = {"version": "windows 10",
"installed apps": {"chrome": "installed",
"python": {"python version": "2.7",
"folder": "c:\python27"},
"minecraft": "not installed"}}
windows2 = {"version": "windows XP",
"installed apps": {"chrome": "not installed",
"python": {"python version": "not installed",
"folder": "c:\python27"},
"minecraft": "not installed"}}
windowsList = [windows1, windows2]
x = {}
for comp in windowsList:
combiner(comp, x)
pp(x) # Use print if you're not running Python >= 3.8
输出:
{'version': {'windows 10': 1, 'windows XP': 1},
'installed apps': {'chrome': {'installed': 1, 'not installed': 1},
'python': {'python version': {'2.7': 1, 'not installed': 1},
'folder': {'c:\\python27': 2}},
'minecraft': {'not installed': 2}}}