我们有这样的数据

input = {
    'a': 3,
    'b': {'g': {'l': 12}},
    'c': {
        'q': 3,
        'w': {'v': 3},
        'r': 8,
        'g': 4
    },
    'd': 4
}

事先不知道将有多少个嵌套级别 我们需要获取最终值的完整地址,所有点都用点或另一个特殊字符分隔 就像这样:

a:3
b.g.l: 12
c.q: 3
c.w.v: 3
etc

我试着用递归函数来解决这个问题.

def recursive_parse(data: dict, cache: Optional[list]=None):
    if cache is None:
        cache = []
    for k in data:
        cache.append(k)
        if not isinstance(data[k], dict):
            print(f"{'.'.join(cache) } :{data[k]}")
            cache.clear()
        else:
            recursive_parse(data[k], cache)

但我在"记住"嵌套词典的前一个关键字时遇到了问题.

a :3
b.g.l :12
c.q :3
w.v :3
r :8
g :4
d :4

解决此问题的正确算法是什么?

推荐答案

对于这一点,使用显式堆栈可能比使用Python调用堆栈更好.由于较高的函数调用开销,在Python中递归速度很慢,并且递归限制相当保守.

def dotted(data):
    result = {}
    stack = list(data.items())
    while stack:
        k0, v0 = stack.pop()
        if isinstance(v0, dict):
            for k1, v1 in v0.items():
                item = ".".join([k0, k1]), v1
                stack.append(item)
        else:
            result[k0] = v0
    return result

演示:

>>> data
{'a': 3,
 'b': {'g': {'l': 12}},
 'c': {'q': 3, 'w': {'v': 3}, 'r': 8, 'g': 4},
 'd': 4}
>>> for k, v in reversed(dotted(data).items()):
...     print(k, v)
... 
a 3
b.g.l 12
c.q 3
c.w.v 3
c.r 8
c.g 4
d 4

Python-3.x相关问答推荐

Python网页抓取:代码输出:汤未定义

PythonPandas 创建一个列并添加到DataFrame

CDKTF ec2 具有特定私有 IP 地址的娱乐

为什么空列表也能起作用?

Python中提取每个组/ID所属特定列中的自然数

基于组/ID从原始数据框中创建两个子数据框

在新数据帧上自动提取两个字符串 python 之间的相等性

包含值超出范围的 ID 的新 DataFrame 列?

正则表达式来识别用 Python 写成单词的数字?

Python pandas将单元格值移动到同一行中的另一个单元格

如何使用pandas python获取数据框中每列的最大长度

具有两个或多个返回参数的函数注释

使用自定义比较删除重复项

sys.stdin.readline() 和 input():读取输入行时哪个更快,为什么?

如何通过命令行将数组传递给python

如何在不使用 @hydra.main() 的情况下获取 Hydra 配置

将 args、kwargs 传递给 run_in_executor

在 Keras 中训练神经网络的零精度

如何从集合中删除多个元素?

Pylint 中的模块PyQt5.QtWidgets错误中没有名称QApplication