在Python中生成字典树中的所有叶到根路径
我有一个“非标准”形式的字典树,如下所示:在Python中生成字典树中的所有叶到根路径,python,recursion,tree,Python,Recursion,Tree,我有一个“非标准”形式的字典树,如下所示: tree = {'0': {'A': {'B': {'C': {}}}}, {'D': {'E': {}}, {'F': {}}}} 叶节点定义为字典键值对,其中值为空字典。 我想将所有叶到根路径提取为列表列表,如下所示: paths_ = [['C', 'B', 'A', '0'], ['E', 'D', '0'], ['F', 'D', '0'
tree = {'0': {'A': {'B': {'C': {}}}},
{'D': {'E': {}},
{'F': {}}}}
叶节点定义为字典键值对,其中值为空字典。
我想将所有叶到根路径提取为列表列表,如下所示:
paths_ = [['C', 'B', 'A', '0'],
['E', 'D', '0'],
['F', 'D', '0']]
如果有帮助的话,路径也可以颠倒
paths_ = [['0', 'A', 'B', 'C'],
['0', 'D', 'E'],
['0', 'D', 'F']]
我知道我必须递归地做这件事,我需要为每个路径创建一个累加器列表。如果函数生成路径列表也很好。到目前为止,我得到的是:
def paths(node, subtree, acc=[]):
if not subtree:
yield [node]+acc
for n, s in subtree.items():
yield paths(n, s, acc)
这并不是我想要的:
paths_ = list(paths('0', tree['0']))
理想情况下,这应该返回列表列表。任何帮助都将不胜感激。假设您确实打算为
树提供以下结构:
tree = {'0': {'A': {'B': {'C': {}}},
'D': {'E': {},
'F': {}}}}
下面是一个类似的paths()
函数,它可以实现您想要的功能:
def paths(tree, cur=()):
if not tree:
yield cur
else:
for n, s in tree.items():
for path in paths(s, cur+(n,)):
yield path
结果:
>>> list(paths(tree))
[('0', 'A', 'B', 'C'), ('0', 'D', 'E'), ('0', 'D', 'F')]
请注意,我使用元组作为默认参数,而不是列表,这是因为。假设树结构是这种格式:
{'0':{'A':{},'B':{}
那么像这样的事情应该会奏效
def paths(nodeId, children, ancestors, allPaths):
ancestors.append(nodeId)
if len(children) == 0:
allPaths.append(ancestors)
else:
for childId in children:
paths(childId, children[childId], ancestors[:], allPaths)
allPaths = []
paths('0', tree['0'], [], allPaths)
像这样的东西应该有用。通常我会先试试这个,但我现在在我的iPad上。如果它不起作用,它应该会给你一些想法。你可以使用类似于所选答案的方法
import collections
def iter_paths(tree, parent_path=()):
for path, node in tree.iteritems():
current_path = parent_path + (path,)
if isinstance(node, collections.Mapping):
for inner_path in iter_paths(node, current_path):
yield inner_path
else:
yield current_path
对于以下内容:
tree={'A':1,
'B':{'B1':1,'B2':2},
'C':{'C1':{'C11':1,'C12':2},'C2':{'C21':1,'C22':2}}
输出应为(产量顺序可能不同):
你能修好这棵树吗?它无效。如果不是树:如果。。。else:
有两个原因:1)更明确地说明这里发生的事情,2)这样无、0
和[]
也是有效的树端状态。@JoelCornett-好主意,在我的答案中添加了else
。太棒了,我忘记了那个可变的默认参数。非常感谢。我已经5年没有研究这个问题了,很高兴看到仍然有解决方案发布;)作为旁注,我一直在阅读流畅的Python,今天我做了Goose打字。很高兴看到您正在使用它。
('A',)
('C', 'C2', 'C22')
('C', 'C2', 'C21')
('C', 'C1', 'C12')
('C', 'C1', 'C11')
('B', 'B1')
('B', 'B2')