从嵌套字典列表创建统计嵌套字典

托默

我有许多嵌套字典的列表,每个字典代表Windows OS,看起来像这样:

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}}}

如您所见,我试图获取列表中每个窗口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'未安装')我尝试过的其他所有操作都没有增加计数器或仅将嵌套形式保留了一个深度。我知道我没有关闭,但是我想念的是什么?

汉普斯·拉尔森

这是一个递归函数,它将执行我认为您要执行的操作。

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}}}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章