Python 字典使用第二个字典替换值(但搜索值而不是整个值)
我试图用dict中的另一个值替换dict中的一个值。从我的搜索中已经做了很多,但我认为我有一个独特的情况,因为我需要搜索一个值的值,而不是替换整个值 到目前为止,我已经尝试过这一方法,并且部分有效:Python 字典使用第二个字典替换值(但搜索值而不是整个值),python,Python,我试图用dict中的另一个值替换dict中的一个值。从我的搜索中已经做了很多,但我认为我有一个独特的情况,因为我需要搜索一个值的值,而不是替换整个值 到目前为止,我已经尝试过这一方法,并且部分有效: input_data = [ { "name": "system1", "other_param": "%param1%", "secret_text&q
input_data = [
{
"name": "system1",
"other_param": "%param1%",
"secret_text": "%secret%",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"%max_date%\\\"\",\"f--status,eq,\\\"Void\\\"\"]"
}
}
]
variables = {
'%secret%': "abc",
'%param1%': "text_param",
'%max_date%': '2018-01-01'
}
def process_variables(dict_obj, dict_vars):
for k, v in dict_obj.items():
for var, val in dict_vars.items():
dict_obj[k] = str(v).replace(var, val)
return dict_obj
for x in input_data:
print(process_variables(x, variables))
预期的结果是:
{
"name": "system1",
"other_param": "text_param",
"secret_text": "abc",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]"
}
}
实际结果:
{
"name":"system1",
"other_param":"%param1%",
"secret_text":"%secret%",
"options":"{\\'conditions\\': \\'[\"f--updated_at,geq,\\\\\"2018-01-01\\\\\"\",\"f--status,eq,\\\\\"Void\\\\\"\"]\\'}"
}
正如您所看到的,它似乎将dict向下展平,而不是替换顶级值
有没有更好的方法来实现这一点?如果需要,我可以更改JSON输入,但我需要进行某种变量替换,因为我有数百个输入,这些输入都是我计划迭代的公共值。我能够将输入数据视为字符串并使用ast(抽象语法树)来获得结果: 输出:
<class 'list'>
[{'name': 'system1', 'other_param': 'text_param', 'secret_text': 'abc', 'options': {'conditions': '["f--updated_at,geq,\\"2018-01-01\\"","f--status,eq,\\"Void\\""]'}}]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]"
},
"other_param": "text_param",
"secret_text": "abc"
}
]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]",
"foo": [
{
"bar": {
"baz": "abc"
}
}
]
},
"other_param": "text_param",
"secret_text": "abc"
}
]
[{'name':'system1','other_param':'text_param','secret_text':'abc','options':{'conditions':'['f--updated_at,geq,\\\\'2018-01-01\\\','f--status,eq,\\\\\\\'Void\\\\\\\\\']}]
我不能保证这是最好的方法,但它简化了过程。值得一试吗?我能够将输入数据作为字符串处理并使用ast(抽象语法树)实现以下结果: 输出:
<class 'list'>
[{'name': 'system1', 'other_param': 'text_param', 'secret_text': 'abc', 'options': {'conditions': '["f--updated_at,geq,\\"2018-01-01\\"","f--status,eq,\\"Void\\""]'}}]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]"
},
"other_param": "text_param",
"secret_text": "abc"
}
]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]",
"foo": [
{
"bar": {
"baz": "abc"
}
}
]
},
"other_param": "text_param",
"secret_text": "abc"
}
]
[{'name':'system1','other_param':'text_param','secret_text':'abc','options':{'conditions':'['f--updated_at,geq,\\\\'2018-01-01\\\','f--status,eq,\\\\\\\'Void\\\\\\\\\']}]
我不能保证这是最好的方法,但它简化了过程。值得一试吗?您可以递归地循环
输入\u数据
,并分别替换每个值。递归循环的好处是,您无需关心input\u数据
嵌套的深度:
def traverse_dict(dct, replacements):
if isinstance(dct, list):
for i, item in enumerate(dct):
dct[i] = traverse_dict(item, variables)
elif isinstance(dct, dict):
for k, v in dct.items():
dct[k] = traverse_dict(v, variables)
else:
# all values in the JSON end up here
if isinstance(dct, str):
for repl in replacements:
if repl in dct:
dct = dct.replace(repl, replacements[repl])
return dct
return dct
result = traverse_dict(input_data, variables)
print(result)
输出:
<class 'list'>
[{'name': 'system1', 'other_param': 'text_param', 'secret_text': 'abc', 'options': {'conditions': '["f--updated_at,geq,\\"2018-01-01\\"","f--status,eq,\\"Void\\""]'}}]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]"
},
"other_param": "text_param",
"secret_text": "abc"
}
]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]",
"foo": [
{
"bar": {
"baz": "abc"
}
}
]
},
"other_param": "text_param",
"secret_text": "abc"
}
]
使
输入\u数据
更加复杂,仍能正确替换:
input_data = [
{
"name": "system1",
"other_param": "%param1%",
"secret_text": "%secret%",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"%max_date%\\\"\",\"f--status,eq,\\\"Void\\\"\"]",
"foo": [
{
"bar": {
"baz": "%secret%",
}
}
]
}
}
]
输出:
<class 'list'>
[{'name': 'system1', 'other_param': 'text_param', 'secret_text': 'abc', 'options': {'conditions': '["f--updated_at,geq,\\"2018-01-01\\"","f--status,eq,\\"Void\\""]'}}]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]"
},
"other_param": "text_param",
"secret_text": "abc"
}
]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]",
"foo": [
{
"bar": {
"baz": "abc"
}
}
]
},
"other_param": "text_param",
"secret_text": "abc"
}
]
您可以递归地循环输入数据,并分别替换每个值。递归循环的好处是,您无需关心
input\u数据
嵌套的深度:
def traverse_dict(dct, replacements):
if isinstance(dct, list):
for i, item in enumerate(dct):
dct[i] = traverse_dict(item, variables)
elif isinstance(dct, dict):
for k, v in dct.items():
dct[k] = traverse_dict(v, variables)
else:
# all values in the JSON end up here
if isinstance(dct, str):
for repl in replacements:
if repl in dct:
dct = dct.replace(repl, replacements[repl])
return dct
return dct
result = traverse_dict(input_data, variables)
print(result)
输出:
<class 'list'>
[{'name': 'system1', 'other_param': 'text_param', 'secret_text': 'abc', 'options': {'conditions': '["f--updated_at,geq,\\"2018-01-01\\"","f--status,eq,\\"Void\\""]'}}]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]"
},
"other_param": "text_param",
"secret_text": "abc"
}
]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]",
"foo": [
{
"bar": {
"baz": "abc"
}
}
]
},
"other_param": "text_param",
"secret_text": "abc"
}
]
使
输入\u数据
更加复杂,仍能正确替换:
input_data = [
{
"name": "system1",
"other_param": "%param1%",
"secret_text": "%secret%",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"%max_date%\\\"\",\"f--status,eq,\\\"Void\\\"\"]",
"foo": [
{
"bar": {
"baz": "%secret%",
}
}
]
}
}
]
输出:
<class 'list'>
[{'name': 'system1', 'other_param': 'text_param', 'secret_text': 'abc', 'options': {'conditions': '["f--updated_at,geq,\\"2018-01-01\\"","f--status,eq,\\"Void\\""]'}}]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]"
},
"other_param": "text_param",
"secret_text": "abc"
}
]
[
{
"name": "system1",
"options": {
"conditions": "[\"f--updated_at,geq,\\\"2018-01-01\\\"\",\"f--status,eq,\\\"Void\\\"\"]",
"foo": [
{
"bar": {
"baz": "abc"
}
}
]
},
"other_param": "text_param",
"secret_text": "abc"
}
]
您正在将“[\”转换为字符串(
str(v).replace(var,val)
),这就是输出混乱的原因。您正在将“[\”转换为字符串(str(v).replace(var,val)
),这就是输出混乱的原因。谢谢。如果键或任何东西恰好被命名为值,那么它会比ast建议安全一点。谢谢。如果键或任何东西恰好被命名为值,那么它会比ast建议安全一点。谢谢e如果键/值匹配,则使用其他答案。我不想替换它们。当然..没问题谢谢。如果键/值匹配,则使用其他答案。我不想替换它们。当然..没问题