给定一个包含元组的名为 outlines 的列表:(level, title),创建一个嵌套字典,其深度基于级别,键值基于标题。
示例列表:
[(1, 摘要)
(二、背景)
(二、方法)
(2, 结果)
(3、统计)
(3, 图片)
(一、简介)]
这应该输出:
{
"Abstract": {
"Background": {},
"Methods": {},
"Results": {
"Statistics": {},
"Images": {}
}
},
"Introduction": {}
}
到目前为止,我已经尝试了递归解决方案,但到目前为止导致了无法追踪的错误行为。这是迄今为止我提出的最佳解决方案,但由于预定义的 for 循环,我无法防止不同级别的重复:
def structure(outlines, current_level=1, previous_title=''):
section = dict()
for i, (level, title) in enumerate(outlines):
if level == current_level:
section[title] = {}
previous_title = title
elif level > current_level:
section[previous_title] = structure(outlines[i:], level)
elif level < current_level:
pass # Unknown
return section
有什么建议吗?
答案 0 :(得分:0)
假设顺序很重要,那么这将起作用:
generator = [
(1, 'Abstract'),
(2, 'Background'),
(2, 'Methods'),
(2, 'Results'),
(3, 'Statistics'),
(3, 'Images'),
(1, 'Introduction')
]
# keep track of latest place in the dict
current_tree = []
# dict that you want to generate
d = {}
for i, value in generator:
# if this, then you are at the highest level
# so just add your value at the top
if current_tree==[] or i==1:
d[value] = {}
current_tree = [value]
# otherwise go back in the tree and add your value
else:
tmp_d = d
for key in current_tree[:i-1]:
tmp_d = tmp_d[key]
tmp_d[value] = {}
current_tree = current_tree[:i] + [value]
返回:
{'Abstract': {'Background': {'Images': {}, 'Statistics': {}},
'Methods': {},
'Results': {}},
'Introduction': {}}
答案 1 :(得分:0)
这是我的递归解决方案:
import json
inlist = [
(1, "Abstract"),
(2, "Background"),
(2, "Methods"),
(2, "Results"),
(3, "Statistics"),
(3, "Images"),
(1, "Introduction"),
]
out = dict()
# IMPORTANT: Dictionaries are ordered in Python 3.6 (under the CPython implementation at least) unlike in previous incarnations.
def addElem(dest_level, new_elem, current_container, current_level=1):
# list(current_container.keys())[-1] gets the most recently added element at the current level.
if (current_level < dest_level):
addElem(dest_level, new_elem, current_container[list(current_container.keys())[-1]], current_level+1)
else:
current_container[new_elem] = dict()
for el in inlist:
addElem(el[0], el[1], out)
print(json.dumps(out, indent=2))
输出:
{
"Abstract": {
"Background": {},
"Methods": {},
"Results": {
"Statistics": {},
"Images": {}
}
},
"Introduction": {}
}
答案 2 :(得分:0)
感谢 John R. Paul,我们已经有了一个可行的解决方案,但我想要一个不依赖于订购字典的解决方案。作为额外的好处,该解决方案是非递归的(尽管 John R. Paul 的解决方案是尾递归的,因此可以简单地重写为使用 while
循环)。
def add_all(generator_of_pairs):
stack = [{}]
for (level, name) in generator_of_pairs:
del stack[level:]
new_dict = {}
stack[level - 1][name] = new_dict
stack.append(new_dict)
return stack[0]
请注意,此解决方案假设从 1 个元素到下一个元素的嵌套级别增加不能超过 1 - 但希望这个假设显然是必要的。