递归重命名字典列表中的字典键
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))
我想了解如何在不改变方法参数的情况下递归地重命名字典列表中的键。
我有以下字典列表:
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))