在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}}

输出应为(产量顺序可能不同):


你能修好这棵树吗?它无效。
如果不是树:
有两个原因: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')