有没有更好的方法来展开和重建嵌套的di

2024-09-24 10:19:02 发布

您现在位置:Python中文网/ 问答频道 /正文

一个我自己发布的解决方案,但我不满意,这太复杂了。在

有时,我们需要将一个dict展平,有时反过来,例如: 嵌套dict如下所示:

{'a': 'A', 'b': {'c': 'BC', 'd': [4, 44, 444]}}

还有一句平淡的话:

^{pr2}$

如我们所见,在本例中,我们使用双下划线来表示嵌套级别。在

我写了两个函数来做这些,请检查我发布的答案,但我还是更喜欢任何robost第三方库或任何其他想法,使这两个函数成为一个服务器?

而且除了之外,我还想知道什么是使值变平的正确方法,哪种类型是一个充满dict对象的列表?让我们这样说,如果我们用dicts intead代替数字4,44,444,那么一个平坦的dict应该是什么呢。在


Tags: 对象方法函数答案服务器类型列表解决方案
2条回答

我编写了两个函数来转换flant和nested dict,但我更喜欢找到一些robost库来处理这些情况。在

def flatten(nested_dict, result=None, prefix=''):
    from collections import OrderedDict
    if result is None:
        result = dict()
    for k, v in nested_dict.items():
        new_k = '__'.join((prefix, k)) if prefix else k
        if not (isinstance(v, dict) or isinstance(v, OrderedDict)):
            result.update({new_k: v})
        else:
            flatten(v, result, new_k)
    return result


def rebuild(flatten_dict, result=None):
    from collections import defaultdict
    import json

    def tree():
        return defaultdict(tree)

    def rec(keys_iter, value):
        _r = tree()
        try:
            _k = next(keys_iter)
            _r[_k] = rec(keys_iter, value)
            return _r
        except StopIteration:
            return value

    if result is None:
        result = dict()

    for k, v in flatten_dict.items():
        keys_nested_iter = iter(k.split('__'))
        cur_level_dict = result
        while True:
            try:
                k = next(keys_nested_iter)
                if k in cur_level_dict:
                    cur_level_dict = cur_level_dict[k]
                else:
                    cur_level_dict[k] = json.loads(json.dumps(rec(keys_nested_iter, v)))
            except StopIteration:
                break

    return result


if __name__ == "__main__":
    my_dict = {'a': 'A',
               'b':
                   {
                       'd': [4, 44, 444],
                       'c': 'BC'
                   }
               }

    my_flatten_dict = flatten(my_dict)
    assert my_flatten_dict == {'a': 'A', 'b__c': 'BC', 'b__d': [4, 44, 444]}

    my_nested_dict = rebuild(my_flatten_dict)
    assert my_nested_dict == {'a': 'A', 'b': {'c': 'BC', 'd': [4, 44, 444]}}

虽然这不是您应该做的事情,但是您可以使用json.dumps将其更改为字符串,并使用re.sub来执行操作

import json, re
d = {'a': 'A', 'b': {'c': 'BC', 'd': [4, 44, 444]}}
def flatten(to_flat):
    return json.loads(re.sub('\}+','}',re.sub('":? *\{"', '__', json.dumps(d))))
print(flatten(d))
# prints {'a': 'A', 'b__c': 'BC', 'd': [4, 44, 444]}

但是rebuilt函数有一个问题,如何知道右大括号在哪里?你不能。但如果它总是位于末尾,你可以:

^{pr2}$

相关问题 更多 >