6
我想要什么
从YAML配置我得到一个Python字典,看起来像这样:继承在配置字典
conf = {
'cc0': {
'subselect':
{'roi_spectra': [0], 'roi_x_pixel_spec': 'slice(400, 1200)'},
'spec':
{'subselect': {'x_property': 'wavenumber'}},
'trace':
{'subselect': {'something': 'jaja', 'roi_spectra': [1, 2]}}
}
}
正如你所看到的关键字是“再选择”通用于所有的子级其价值总是一个字典,但其存在是可选的。嵌套量可能会改变。 我在寻找一个功能,可以让我做到以下几点:
# desired function that uses recursion I belive.
collect_config(conf, 'trace', 'subselect')
其中“追踪”是类型的字典字典的关键,可能有一个“子查询”字典的价值。
和它应该返回
{'subselect':{
'something': 'jaja',
'roi_spectra': [1, 2],
'roi_x_pixel_spec':
'slice(400, 1200)'
}
,或者如果我问
collect_config(conf, "spec", "subselect")
它应该返回
{'subselect':{
'roi_spectra': [0],
'roi_x_pixel_spec':
'slice(400, 1200)',
'x_property': 'wavenumber'
}
我基本上要什么,是传递值的方法从顶级到低级的一个关键点,并且具有较低级别的覆盖e顶级值。 很像继承类,但与字典。
所以我需要一个遍历字典的函数,找到所需键的路径(这里是“trace”或“spec”)并用更高级别的值填充它的值(这里是“subselect”),但只有当heigher水平值不存在。
一个蹩脚的解决方案
目前,我有一种实现的,看起来如下。
# This traverses the dict and gives me the path to get there as a list.
def traverse(dic, path=None):
if not path:
path=[]
if isinstance(dic, dict):
for x in dic.keys():
local_path = path[:]
local_path.append(x)
for b in traverse(dic[x], local_path):
yield b
else:
yield path, dic
# Traverses through config and searches for the property(keyword) prop.
# higher levels will update the return
# once we reached the level of the name (max_depth) only
# the path with name in it is of interes. All other paths are to
# be ignored.
def collect_config(config, name, prop, max_depth):
ret = {}
for x in traverse(config):
path = x[0]
kwg = path[-1]
value = x[1]
current_depth = len(path)
# We only care about the given property.
if prop not in path:
continue
if current_depth < max_depth or (current_depth == max_depth and name in path):
ret.update({kwg: value})
return ret
,然后我可以
叫它read_config(conf, "trace", 'subselect', 4)
,并得到
{'roi_spectra': [0],
'roi_x_pixel_spec': 'slice(400, 1200)',
'something': 'jaja'}
更新
jdehesa是几乎没有,但我也可以有一个配置,看起来像:
conf = {
'subselect': {'test': 'jaja'}
'bg0': {
'subselect': {'roi_spectra': [0, 1, 2]}},
'bg1': {
'subselect': {'test': 'nene'}},
}
collect_config(conf, 'bg0', 'subselect')
{'roi_spectra': [0, 1, 2]}
,而不是
{'roi_spectra': [0, 1, 2], 'test': 'jaja'}
所以基本上你想要由最后一个参数命名的字典(提供详细信息),用从第二个参数加上最后一个参数形成的路径加载的覆盖更新。 –
函数应该如何找出顶级'conf'字典中的关键字?在你的例子中,只有一个键“cc0”。如果总是只有一个键,那有什么意义?如果有时不止一个,应该采用哪一个? –
你可以检查,如果这可以帮助你(https://stackoverflow.com/questions/9807634/find-all-occurrences-of-a-key-in-nested-python-dictionaries-and-lists) –