如何将嵌套字典转换为列表的字符串

How to convert nested dictionary into the string of list

我有这个嵌套的 python 字典

dictionary = {'a':'1', 'b':{'c':'2', 'd':{'z':'5',  'e':{'f':'13', 'g':'14'}}}}

所以推荐的输出将是:

output = ['a:1', 'b:c:2', 'b:d:z:5', 'b:d:e:f:13', 'b:d:e:g:13']

使用recursive function而不使用递归函数

在这种情况下,我总是喜欢先尝试解决容易的部分。

def flatten_dict(dictionary):
    output = []
    for key, item in dictionary.items():
        if isinstance(item, dict):
            output.append(f'{key}:???')  # Hm, here is the difficult part
        else:
            output.append(f'{key}:{item}')
    return output

尝试 flatten_dict(dictionary) 现在打印 ['a:1', 'b:???'] 这显然不够好。一方面,列表中的三个项目太少了。

首先,我想改用生成器函数。这目前比较复杂,但稍后会得到回报。

def flatten_dict(dictionary):
    return list(flatten_dict_impl(dictionary))

def flatten_dict_impl(dictionary):
    for key, item in dictionary.items():
        if isinstance(item, dict):
            yield f'{key}:???'
        else:
            yield f'{key}:{item}'

输出还没有变化。是时候回顾了。

你希望输出是一个平面列表,这意味着我们必须在 item 是字典的情况下产生多个东西。只是,什么东西?让我们尝试在这个子词典中插入对 flatten_dict_impl 的递归调用,这似乎是最直接的方法。

# flatten_dict is unchanged

def flatten_dict_impl(dictionary):
    for key, item in dictionary.items():
        if isinstance(item, dict):
            for value in flatten_dict_impl(item):
                yield f'{key}:{value}'
        else:
            yield f'{key}:{item}'

输出现在是 ['a:1', 'b:c:2', 'b:d:z:5', 'b:d:e:f:13', 'b:d:e:g:14'],这是你想要的输出,除了最后的 14,但我认为这是你的错字。

现在是 non-recursive 路线。为此,我们需要自己管理一些状态,因为我们需要知道我们有多深。

def flatten_dict_nonrecursive(dictionary):
    return list(flatten_dict_nonrecursive_impl(dictionary))

def flatten_dict_nonrecursive_impl(dictionary):
    dictionaries = [iter(dictionary.items())]
    keys = []
    while dictionaries:
        try:
            key, value = next(dictionaries[-1])
        except StopIteration:
            dictionaries.pop()
            if keys:
                keys.pop()
        else:
            if isinstance(value, dict):
                keys.append(key)
                dictionaries.append(iter(value.items()))
            else:
                yield ':'.join(keys + [key, value])

现在这给出了正确的输出,但更不容易理解,而且更长。我也花了很长时间才做对。可能有更短和更明显的方法来做到这一点,但我错过了,但通常递归问题更容易用递归函数解决。

这种方法仍然有用:如果您的字典嵌套了数百或数千层,那么尝试递归执行它可能会溢出堆栈。

希望对您有所帮助。让我知道是否需要了解更多细节或其他内容。

您可以使用 NestedDict。首先安装ndicts

pip install ndicts

然后:

from ndicts.ndicts import NestedDictionary

dictionary = {'a': '1', 'b': {'c' :'2', 'd': {'z': '5', 'e': {'f': '13', 'g': '14'}}}}
nd = NestedDict(dictionary)

output = [":".join((*key, value)) for key, value in nd.items()]