Python过滤器嵌套dict给定的键名称列表

2024-05-14 07:52:50 发布

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

有没有一种方法可以过滤Python中嵌套的dict,这样我就只能看到我指定的键了吗? 示例:

x = {
  "field": [
    {
      "nm_field": "ch_origem_sistema_chave",
      "inf_tabelado": {
        "dropdown_value": "",
        "dropdown_key": "",
        "url_lista": "",
        "chave_relacional": ""
      },
    },
    {
      "nm_field": "ax_andamento_data",
      "inf_tabelado": {
        "dropdown_value": "",
        "dropdown_key": "",
        "url_lista": "",
        "chave_relacional": ""
      },
    }
  ],
  "_metadata": {
    "dt_reg": "22/01/2014 16:17:16",
    "dt_last_up": "10/04/2014 16:30:44",
  },
  "url_detalhes": "/DetalhesDocsPro.aspx",
  "url_app": "/docspro",
}

y = filter(x, ['dropdown_value', 'nm_field', 'url_app', 'dt_reg'])

那么变量y应该是:

^{pr2}$

我尝试过使用defaultdict做一些事情,但是在任何级别的递归中都没有成功。我还发现在处理不同的数据结构时很困难。在


Tags: 方法keyappurlfieldvaluedtreg
2条回答

这里有一个解决方案,它以深度优先的方式遍历结构,以找到要检查的“叶”节点是否在要保留的元素列表中。当它找到这样一个元素时,它用del从字典中删除它。(所以这是在适当的地方完成的。)

def fltr(d, vals):
    if isinstance(d, dict):
        vals_to_del = []
        for k in d:
            if k in vals:
                continue
            if not isinstance(d[k], list) and not isinstance(d[k], dict):
                if k not in vals:
                    vals_to_del.append(k)
            else:
                fltr(d[k], vals)
        for k in vals_to_del:
            del d[k]
    elif isinstance(d, list):
        for i in d:
            fltr(i, vals)

请注意,我没有定义一个名为filter的函数,因为它是一个内置函数,您不想隐藏它。在

^{pr2}$

以下是2rs2ts的答案的修改版本,它返回一个新对象而不是修改旧对象(并处理非叶节点上的过滤):

import copy

def fltr(node, vals):
    if isinstance(node, dict):
        retVal = {}
        for key in node:
            if key in vals:
                retVal[key] = copy.deepcopy(node[key])
            elif isinstance(node[key], list) or isinstance(node[key], dict):
                child = fltr(node[key], vals)
                if child:
                    retVal[key] = child
        if retVal:
             return retVal
        else:
             return None
    elif isinstance(node, list):
        retVal = []
        for entry in node:
            child = fltr(entry, vals)
            if child:
                retVal.append(child)
        if retVal:
            return retVal
        else:
            return None

带着这个,你会打电话来的

^{pr2}$

然后得到

{
    "field": [
        {
            "inf_tabelado": {
                "dropdown_value": ""
            },
            "nm_field": "ch_origem_sistema_chave"
        },
        {
            "inf_tabelado": {
                "dropdown_value": ""
            },
            "nm_field": "ax_andamento_data"
        }
    ],
    "url_app": "/docspro",
    "_metadata": {
        "dt_reg": "22/01/2014 16:17:16"
    }
}

请注意,如果所有内容都被过滤,则返回None。例如

fltr(x, [])

将始终返回None,无论x中是什么。在

相关问题 更多 >

    热门问题