从扁平字典创建嵌套字典 [英] Creating a nested dictionary from a flattened dictionary

查看:35
本文介绍了从扁平字典创建嵌套字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个扁平的字典,我想把它做成一个嵌套的字典,形式为

I have a flattened dictionary which I want to make into a nested one, of the form

flat = {'X_a_one': 10,
        'X_a_two': 20, 
        'X_b_one': 10,
        'X_b_two': 20, 
        'Y_a_one': 10,
        'Y_a_two': 20,
        'Y_b_one': 10,
        'Y_b_two': 20}

我想把它转换成表格

nested = {'X': {'a': {'one': 10,
                      'two': 20}, 
                'b': {'one': 10,
                      'two': 20}}, 
          'Y': {'a': {'one': 10,
                      'two': 20},
                'b': {'one': 10,
                      'two': 20}}}

平面字典的结构是这样的,不应该有任何歧义的问题.我希望它适用于任意深度的字典,但性能并不是真正的问题.我见过很多用于展平嵌套字典的方法,但基本上没有用于嵌套展平字典的方法.存储在字典中的值要么是标量,要么是字符串,绝不是可迭代的.

The structure of the flat dictionary is such that there should not be any problems with ambiguities. I want it to work for dictionaries of arbitrary depth, but performance is not really an issue. I've seen lots of methods for flattening a nested dictionary, but basically none for nesting a flattened dictionary. The values stored in the dictionary are either scalars or strings, never iterables.

到目前为止我有一些可以接受输入的东西

So far I have got something which can take the input

test_dict = {'X_a_one': '10',
             'X_b_one': '10',
             'X_c_one': '10'}

输出

test_out = {'X': {'a_one': '10', 
                  'b_one': '10', 
                  'c_one': '10'}}

使用代码

def nest_once(inp_dict):
    out = {}
    if isinstance(inp_dict, dict):
        for key, val in inp_dict.items():
            if '_' in key:
                head, tail = key.split('_', 1)

                if head not in out.keys():
                    out[head] = {tail: val}
                else:
                    out[head].update({tail: val})
            else:
                out[key] = val
    return out

test_out = nest_once(test_dict)

但是我在弄清楚如何将它变成递归创建字典的所有级别的东西时遇到了麻烦.

But I'm having trouble working out how to make this into something which recursively creates all levels of the dictionary.

任何帮助将不胜感激!

(至于我为什么要这样做:我有一个文件,其结构相当于一个嵌套的字典,我想将此文件的内容存储在 NetCDF 文件的属性字典中并稍后检索它.但是只有 NetCDF允许你把平面字典作为属性,所以我想解开我之前存储在 NetCDF 文件中的字典.)

(As for why I want to do this: I have a file whose structure is equivalent to a nested dict, and I want to store this file's contents in the attributes dictionary of a NetCDF file and retrieve it later. However NetCDF only allows you to put flat dictionaries as the attributes, so I want to unflatten the dictionary I previously stored in the NetCDF file.)

推荐答案

这是我的看法:

def nest_dict(flat):
    result = {}
    for k, v in flat.items():
        _nest_dict_rec(k, v, result)
    return result

def _nest_dict_rec(k, v, out):
    k, *rest = k.split('_', 1)
    if rest:
        _nest_dict_rec(rest[0], v, out.setdefault(k, {}))
    else:
        out[k] = v

flat = {'X_a_one': 10,
        'X_a_two': 20, 
        'X_b_one': 10,
        'X_b_two': 20, 
        'Y_a_one': 10,
        'Y_a_two': 20,
        'Y_b_one': 10,
        'Y_b_two': 20}
nested = {'X': {'a': {'one': 10,
                      'two': 20}, 
                'b': {'one': 10,
                      'two': 20}}, 
          'Y': {'a': {'one': 10,
                      'two': 20},
                'b': {'one': 10,
                      'two': 20}}}
print(nest_dict(flat) == nested)
# True

这篇关于从扁平字典创建嵌套字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆