递归重命名字典列表中的字典键

Rename dict keys in a list of dicts recursively

我想了解如何在不改变方法参数的情况下递归地重命名字典列表中的键。

我有以下字典列表:

filters = [
    {
        'or': [
        {
                'and': [
                {
                    "column": {
                        "type": "string",
                        "name": "field_name"
                    },
                    "operator": "==",
                    "value": "field_value"
                },
                {
                    "column": {
                        "type": "string",
                        "name": "field_2_name"
                    },
                    "operator": "!=",
                    "value": "field_2_value"
                }
            ]
        },
        {
                'not': [
                {
                    "column": {
                        "type": "number",
                        "name": "field_3_name"
                    },
                    "operator": "==",
                    "value": "field_3_value"
                }
            ]
        }
    ]
}]

这是我期望达到的效果:

filters = [
    {
        'or': [
            {
                'and': [
                    {'field': 'field_name', 'op': '==', 'value': 'field_value'},
                    {'field': 'field_2_name', 'op': '!=', 'value': 'field_2_value'},
                ]
            },
            {
                'not': [
                    {'field': 'field_3_name', 'op': '==', 'value': 'field_3_value'}
                ]
            },
        ],
    }

]

有什么办法可以解决这个问题?

谢谢!

递归函数应该可以工作,如果它们包含 column 则更改子字典,否则更深入地递归其他操作。

def change(collection):
    if isinstance(collection, list):
        return [change(d) for d in collection]
    if isinstance(collection, dict):
        if "column" in collection:
            return {
                "field": collection["column"]["name"],
                "value": collection["value"],
                "op": collection["operator"]
            }
        else:
            return {op: change(val) for op, val in collection.items()}

res = change(filters)

结果:

[{'or': [{'and': [{'field': 'field_name', 'op': '==', 'value': 'field_value'},
                  {'field': 'field_2_name', 'op': '!=', 'value': 'field_2_value'}]},
         {'not': [{'field': 'field_3_name', 'op': '==', 'value': 'field_3_value'}]}]}]

很简单,您编写一个递归函数来修复您的数据结构。我假设你不想改变原来的。

def fixup(d):
    if isinstance(d,list):
        return [fixup(x) for x in d]
    elif not isinstance(d,dict):
        return d
    elif needs_mangling(d):
        return mangler(d)
    else:
        return {k:fixup(v) for k,v in d.items()}

根据需要添加修饰函数。

这是否满足您的场景?

def change(obj):
    # if recusive parameter is a list
    if isinstance(obj, list):
        # run next recursive iteration for each item in list
        for i in range(len(obj)):
            obj[i] = change(obj[i])
        return obj

    # if parameter is a dict
    if isinstance(obj, dict):
        # 1st case is to convert the object
        if "operator" in obj:
            return {"field": obj["column"]["name"], "op": obj["operator"], "value": obj["value"]}

        # 2nd case is to go deeper into recursion with object values
        else:
            for key in obj:
                obj[key] = change(obj[key])
            return obj


print(change(filters))