用映射字典的值替换嵌套字典中的占位符
Replace placeholder in nested dict with values of mapping dict
我有一个嵌套的字典,它可以在键和值中包含占位符。
example_dict = {'dict1': {'%(map3)s': {'data': 'tmp'},
'%(map2)s': {'freshdata': 'testtest'}},
'dict2': {'%(map3)s': {'data': '%(map1)s'}, '%(map3)s': {'status': 'available'}}}
我有一个映射字典,带有占位符映射:
mapping_dict= {
"map1": [1,2,2],
"map2": "qwerz",
"map3": "asdfasdf"
}
如果占位符位于 VALUE 位置,则 mapping_dict 的相应映射也可能包含另一种数据类型而不是字符串作为值,例如列表或一个整数。如何将此数据类型传递给原始字典?我不知道如何制作占位符,例如获取列表。
Info:可能 mapping_dict 包含的键多于给定的 example_dict 包含的键。
我想要一个函数,用 mapping_dict.
的值替换给定字典的占位符
什么是好的递归实现?
这是一个递归选项,删除现有键并添加新键,应用 "format" 和 "named" 占位符。注意:我们在这种情况下修改输入字典:
from pprint import pprint
example_dict = {'dict1': {'%(map1)s': {'data': 'tmp'}, '%(map2)s': {'freshdata': 'testtest'}},
'dict2': {'%(map1)s': {'data': '%(map1)s'}, '%(map2)s': {'status': 'available'}}}
mapping_dict= {
"map1": "asdf",
"map2": "qwerz",
}
def apply_placeholder(d, placeholder):
for key, value in d.items():
del d[key]
if isinstance(value, dict):
d[key % placeholder] = value
apply_placeholder(value, placeholder)
else:
d[key % placeholder] = value % placeholder
apply_placeholder(example_dict, mapping_dict)
pprint(example_dict)
打印:
{'dict1': {'asdf': {'data': 'tmp'}, 'qwerz': {'freshdata': 'testtest'}},
'dict2': {'asdf': {'data': 'asdf'}, 'qwerz': {'status': 'available'}}}
我不太喜欢这里的 del
调用和修改输入对象,很高兴看到更好的选择。
我认为这可以递归地执行您想要的操作。它创建原始字典的副本,然后对其进行修改,以便可以重复使用原始字典。
from pprint import pprint
import copy
try:
stringtype = basestring
except NameError:
stringtype = str # Python 3
def subst(mapping, replacements):
def do_subst(mapping, replacements):
for k, v in list(mapping.items()):
newk, newv = k, v
changed = False
if isinstance(k, stringtype):
newk = k % replacements
if newk != k:
changed = True
if isinstance(v, stringtype):
newv = v % replacements
if newv != v:
changed = True
elif isinstance(v, dict):
newv = do_subst(v, replacements)
if newv != v:
changed = True
if changed:
del mapping[k]
mapping[newk] = newv
return mapping
return do_subst(copy.deepcopy(mapping), replacements)
example_dict = {'dict1': {'%(map1)s': {'data': 'tmp'},
'%(map2)s': {'freshdata': 'testtest'}},
'dict2': {'%(map1)s': {'data': '%(map1)s'},
'%(map2)s': {'status': 'available'}}}
mapping_dict= {"map1": "asdf", "map2": "qwerz"}
print('Before')
pprint(example_dict)
result = subst(example_dict, mapping_dict)
print('After')
pprint(result)
输出:
Before
{'dict1': {'%(map1)s': {'data': 'tmp'}, '%(map2)s': {'freshdata': 'testtest'}},
'dict2': {'%(map1)s': {'data': '%(map1)s'},
'%(map2)s': {'status': 'available'}}}
After
{'dict1': {'asdf': {'data': 'tmp'}, 'qwerz': {'freshdata': 'testtest'}},
'dict2': {'asdf': {'data': 'asdf'}, 'qwerz': {'status': 'available'}}}
使用堆栈来导航键值对,你可以弹出键来重命名它们,对于值,做同样的事情,除了尝试看看你是否可以使用 [= 将它们评估为 Python 文字12=] 来处理您的列表案例。
import ast
from copy import deepcopy
example_dict = {
'dict1': {
'%(map3)s': {'data': 'tmp'},
'%(map2)s': {'freshdata': 'testtest'}
},
'dict2': {
'%(map3)s': {'data': '%(map1)s'}
}
}
mapping_dict= {
"map1": [1,2,2],
"map2": "qwerz",
"map3": "asdfasdf"
}
def sub_placeholders(orig, subs):
d = deepcopy(orig)
todo = [d]
while todo:
nxt = todo.pop()
for k, v in nxt.items():
nxt[k % mapping_dict] = nxt.pop(k)
if isinstance(v, dict):
todo.append(v)
elif isinstance(v, str):
nxt[k] = v % subs
try:
nxt[k] = ast.literal_eval(nxt[k])
except ValueError:
pass
return d
运行 sub_placeholders(example_dict, example_mapping)
会给你:
{'dict1': {'asdfasdf': {'data': 'tmp'}, 'qwerz': {'freshdata': 'testtest'}},
'dict2': {'asdfasdf': {'data': [1, 2, 2]}}}
我有一个嵌套的字典,它可以在键和值中包含占位符。
example_dict = {'dict1': {'%(map3)s': {'data': 'tmp'},
'%(map2)s': {'freshdata': 'testtest'}},
'dict2': {'%(map3)s': {'data': '%(map1)s'}, '%(map3)s': {'status': 'available'}}}
我有一个映射字典,带有占位符映射:
mapping_dict= {
"map1": [1,2,2],
"map2": "qwerz",
"map3": "asdfasdf"
}
如果占位符位于 VALUE 位置,则 mapping_dict 的相应映射也可能包含另一种数据类型而不是字符串作为值,例如列表或一个整数。如何将此数据类型传递给原始字典?我不知道如何制作占位符,例如获取列表。
Info:可能 mapping_dict 包含的键多于给定的 example_dict 包含的键。
我想要一个函数,用 mapping_dict.
的值替换给定字典的占位符什么是好的递归实现?
这是一个递归选项,删除现有键并添加新键,应用 "format" 和 "named" 占位符。注意:我们在这种情况下修改输入字典:
from pprint import pprint
example_dict = {'dict1': {'%(map1)s': {'data': 'tmp'}, '%(map2)s': {'freshdata': 'testtest'}},
'dict2': {'%(map1)s': {'data': '%(map1)s'}, '%(map2)s': {'status': 'available'}}}
mapping_dict= {
"map1": "asdf",
"map2": "qwerz",
}
def apply_placeholder(d, placeholder):
for key, value in d.items():
del d[key]
if isinstance(value, dict):
d[key % placeholder] = value
apply_placeholder(value, placeholder)
else:
d[key % placeholder] = value % placeholder
apply_placeholder(example_dict, mapping_dict)
pprint(example_dict)
打印:
{'dict1': {'asdf': {'data': 'tmp'}, 'qwerz': {'freshdata': 'testtest'}},
'dict2': {'asdf': {'data': 'asdf'}, 'qwerz': {'status': 'available'}}}
我不太喜欢这里的 del
调用和修改输入对象,很高兴看到更好的选择。
我认为这可以递归地执行您想要的操作。它创建原始字典的副本,然后对其进行修改,以便可以重复使用原始字典。
from pprint import pprint
import copy
try:
stringtype = basestring
except NameError:
stringtype = str # Python 3
def subst(mapping, replacements):
def do_subst(mapping, replacements):
for k, v in list(mapping.items()):
newk, newv = k, v
changed = False
if isinstance(k, stringtype):
newk = k % replacements
if newk != k:
changed = True
if isinstance(v, stringtype):
newv = v % replacements
if newv != v:
changed = True
elif isinstance(v, dict):
newv = do_subst(v, replacements)
if newv != v:
changed = True
if changed:
del mapping[k]
mapping[newk] = newv
return mapping
return do_subst(copy.deepcopy(mapping), replacements)
example_dict = {'dict1': {'%(map1)s': {'data': 'tmp'},
'%(map2)s': {'freshdata': 'testtest'}},
'dict2': {'%(map1)s': {'data': '%(map1)s'},
'%(map2)s': {'status': 'available'}}}
mapping_dict= {"map1": "asdf", "map2": "qwerz"}
print('Before')
pprint(example_dict)
result = subst(example_dict, mapping_dict)
print('After')
pprint(result)
输出:
Before
{'dict1': {'%(map1)s': {'data': 'tmp'}, '%(map2)s': {'freshdata': 'testtest'}},
'dict2': {'%(map1)s': {'data': '%(map1)s'},
'%(map2)s': {'status': 'available'}}}
After
{'dict1': {'asdf': {'data': 'tmp'}, 'qwerz': {'freshdata': 'testtest'}},
'dict2': {'asdf': {'data': 'asdf'}, 'qwerz': {'status': 'available'}}}
使用堆栈来导航键值对,你可以弹出键来重命名它们,对于值,做同样的事情,除了尝试看看你是否可以使用 [= 将它们评估为 Python 文字12=] 来处理您的列表案例。
import ast
from copy import deepcopy
example_dict = {
'dict1': {
'%(map3)s': {'data': 'tmp'},
'%(map2)s': {'freshdata': 'testtest'}
},
'dict2': {
'%(map3)s': {'data': '%(map1)s'}
}
}
mapping_dict= {
"map1": [1,2,2],
"map2": "qwerz",
"map3": "asdfasdf"
}
def sub_placeholders(orig, subs):
d = deepcopy(orig)
todo = [d]
while todo:
nxt = todo.pop()
for k, v in nxt.items():
nxt[k % mapping_dict] = nxt.pop(k)
if isinstance(v, dict):
todo.append(v)
elif isinstance(v, str):
nxt[k] = v % subs
try:
nxt[k] = ast.literal_eval(nxt[k])
except ValueError:
pass
return d
运行 sub_placeholders(example_dict, example_mapping)
会给你:
{'dict1': {'asdfasdf': {'data': 'tmp'}, 'qwerz': {'freshdata': 'testtest'}},
'dict2': {'asdfasdf': {'data': [1, 2, 2]}}}