2014-12-27 58 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)