2014-12-27 55 views
1

我正在尝试编写函数以在列表格式列表和嵌套字典格式之间移动树结构。下面的代码给出了两个函数(paths2treetree2paths)。从列表列表转换为嵌套树(paths2tree函数)可以正常工作,但反向转换(tree2paths,构建为迭代器)无法生成正确的列表。以错误的格式在嵌套树中列表返回列表列表转换为列表列表

最后一小段代码测试了这两个函数。在tree2paths转换中,打印语句表明该函数正在生成正确的列表,但yield语句似乎并未将该信息返回给调用语句。 tree2paths函数返回正确的列表,但格式不正确。

任何想法为什么yield语句没有返回可用列表?

def paths2tree(paths): 
    tree = {} 
    for path in paths: 
     current_level = tree 
     for part in path: 
      if part not in current_level: 
       current_level[part] = {} 
      current_level = current_level[part]  
    return tree 


def tree2paths(tree,base=None): 
     for branch in tree.keys() : 
      if base is None: 
       subbase = [branch] 
      else: 
       subbase = base+[branch] 
      yield subbase 
      print subbase 
      newbase = list(tree2paths(tree[branch],subbase)) 
      yield newbase 
paths = [['root','boot','bah'], 
     ['root','boot'], 
     ['root','boot','bad'], 
     ['root'], 
     ['root','toot'], 
     ['root','toot','tah'], 
     ['root','toot','tad'], 
     ['root','toot','tad','two'] 
     ] 

atree = paths2tree(paths)  
print atree  
newpaths = list(tree2paths(atree)) 
print newpaths 

回答

1

的问题就在这里:

newbase = list(tree2paths(tree[branch],subbase)) 
yield newbase 

的问题是,list(tree2paths(tree[branch],subbase))是列表的列表,包含你的路。当你只是产生这个列表时,你会得到newbase列表中的两个元素,['root'][['root', 'toot'], ..., ['root', 'boot', 'bah'], []]]。你需要做的是迭代虽然newbase,并产生每一个元素:

def tree2paths(tree,base=None): 
    for branch in tree.keys() : 
     if base is None: 
      subbase = [branch] 
     else: 
      subbase = base+[branch] 
     yield subbase 
     print subbase 
     newbase = list(tree2paths(tree[branch],subbase)) 
     for i in newbase: 
      yield i 

由此产生的预期效果:

['root'] 
['root', 'toot'] 
['root', 'toot', 'tad'] 
['root', 'toot', 'tad', 'two'] 
['root', 'toot', 'tah'] 
['root', 'boot'] 
['root', 'boot', 'bad'] 
['root', 'boot', 'bah'] 

注意的是Python 3.3,你可以只写yield from tree2paths(tree[branch],subbase)