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) –