将嵌套dict结构展平为数据

2024-04-24 04:36:11 发布

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

对于一些后期处理,我需要像这样展平一个结构

{'foo': {
          'cat': {'name': 'Hodor',  'age': 7},
          'dog': {'name': 'Mordor', 'age': 5}},
 'bar': { 'rat': {'name': 'Izidor', 'age': 3}}
}

此数据集中:

^{pr2}$

所以我写了这个函数:

def flatten(data, primary_keys):
    out = []
    keys = copy.copy(primary_keys)
    keys.reverse()
    def visit(node, primary_values, prim):
        if len(prim):
            p = prim.pop()
            for key, child in node.iteritems():
                primary_values[p] = key
                visit(child, primary_values, copy.copy(prim))
        else:
            new = copy.copy(node)
            new.update(primary_values)
            out.append(new)
    visit(data, { }, keys)
    return out

out = flatten(a, ['foo', 'bar'])   

我不太满意,因为我必须使用copy.copy来保护我的输入。显然,当使用flatten时,不希望更改输入。在

然后我考虑了一个替代方案,它使用更多的全局变量(至少是全局变量到flatten)并使用索引,而不是直接将primary_keys传递给visit。然而,这并不能真正帮助我摆脱丑陋的初始版本:

    keys = copy.copy(primary_keys)
    keys.reverse()

这是我的最终版本:

def flatten(data, keys):
    data = copy.copy(data)
    keys = copy.copy(keys)
    keys.reverse()
    out = []
    values = {}
    def visit(node, id):
        if id:
            id -= 1
            for key, child in node.iteritems():
               values[keys[id]] = key
               visit(child, id)
        else:
            node.update(values)
            out.append(node)
    visit(data, len(keys))
    return out    

有没有更好的实现(可以避免使用copy.copy)?在


Tags: keynameidnodechilddatadefvisit
1条回答
网友
1楼 · 发布于 2024-04-24 04:36:11

编辑:修改以考虑可变字典深度。在

{{my}可以通过使用下面的函数来避免调用

def flatten(data, keys):
    out = []
    values = {}
    def visit(node, id):
        if id:
            id -= 1
            for key, child in node.items():
               values[keys[id]] = key
               visit(child, id)
        else:
            out.append(merge(node, values))  # use merge instead of update
    visit(data, len(keys))
    return out     

我不明白的一点是,为什么需要保护keys输入。我看不到他们在任何地方被修改。在


上一个答案

列表理解怎么样?在

^{pr2}$

棘手的部分是合并字典时不使用update(它返回None)。在

相关问题 更多 >