【问题标题】:Get nested arrays out of a dictionary从字典中获取嵌套数组
【发布时间】:2015-03-23 18:19:42
【问题描述】:

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

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

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

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

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

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

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

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

【问题讨论】:

  • 您能详细说明一下吗? IE 如何在 Python 中做到这一点?
  • 唉,这个问题究竟是什么值得反对的?

标签: python dictionary


【解决方案1】:

为了完整起见,以下是带有类型参数的公认答案,可让您过滤掉要保留的值类型。在我的例子中,这只是数组值,但是这种行为对于解析 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'}

【讨论】:

    【解决方案2】:

    这是我与一些用于语言处理的决策树一起使用的函数,它不是您想要的,但它是相同的基本思想。

    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'}
    

    【讨论】:

    • 我可能会更改 type(val) is not dict 来解释第二个条件,即它也必须是一个数组。我们的结果中还有其他值不是数组,可能是字符串或其他东西,我将有效地忽略它们。但除此之外,我认为这将按原样工作。谢谢。我远离主要电脑,所以在我有机会安装后会回来并标记为已接受。
    猜你喜欢
    • 2021-12-24
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 2021-05-10
    相关资源
    最近更新 更多