从字典中获取嵌套数组

Get nested arrays out of a dictionary

我正在尝试解析模拟结果以提取所有 numpy 数组结果。当模拟一个简单的 material 时,我们可能会得到一个包含数组值的字典:

{'material1':array, 'material2':array, ...}

在更复杂的 material 模拟中,我们最终得到嵌套字典,例如:

{'material1': {'shellmaterial':array, 'corematerial':array}}

嵌套的深度是任意的,我想做的是创建一个图,其中所有可用的数组都returned给用户,以它们的嵌套命名。因此,例如,上面的结构最终会像:

{'material1.shellmaterial' : array, 'material1.corematerial' : array}

然后我们将它们放在下拉菜单中。以便于在情节中查看。有没有人有一个很好的方法来遍历任意嵌套的字典和 return 只有数组类型值 和上面所示的新键?

为了 json 兼容性,结果必须以这种方式存储,所以我不能真的回去重构来避免这种情况。

这是我用一些决策树来处理语言的一个函数,它不是你想要的,但它的基本思想是一样的。

def nodeMapForDict(d):
    node_map = []
    node_path = [] 
    def nodeRecursiveMap(d, node_path): 
        for key, val in d.items():
            if type(val) is not dict: node_map.append(node_path + [key]) 
            if type(val) is dict: 
                nodeRecursiveMap(val, node_path + [key])
    nodeRecursiveMap(d, node_path)
    return node_map

这是适合您的用例的一个:

def flattenDict(d):
    node_map = {}
    node_path = [] 
    def nodeRecursiveMap(d, node_path): 
        for key, val in d.items():
            if type(val) is not dict: node_map['.'.join(node_path + [key])] = val 
            if type(val) is dict: 
                nodeRecursiveMap(val, node_path + [key])
    nodeRecursiveMap(d, node_path)
    return node_map

示例:

d= {'d': [1, 2, 3, 4], 'e': {'b': {'c': 1}}, 'a': {'b': 'c'}}
In [49]: flattenDict(d)
Out[49]: {'d': [1, 2, 3, 4], 'e.b.c': 1, 'a.b': 'c'}

为了完整起见,这里是接受的答案,其中包含一个类型参数,可让您过滤掉要保留的值类型。在我的例子中,这只是数组值,但这种行为对于解析 json 文件或特别是我们的模拟程序数据的结果非常有用。

def flattenDict(d, *types):
    node_map = {}
    node_path = [] 
    def nodeRecursiveMap(d, node_path): 
        for key, val in d.items():
            if type(val) in types: 
                node_map['.'.join(node_path + [key])] = val 
            if type(val) is dict: 
                nodeRecursiveMap(val, node_path + [key])
    nodeRecursiveMap(d, node_path)
    return node_map

例如只保留整数和字符串:

d= {'d': [1, 2, 3, 4], 'e': {'b': {'c': 1}}, 'a': {'b': 'c'}}
In [1]: flattenDict(d, int, basestring)
Out[2]: {'e.b.c': 1, 'a.b': 'c'}