2014-12-11 190 views
0

到字典中它不是一個嚴格的嵌套列表,它是一個樹狀結構,看起來像:轉換嵌套列表蟒蛇

A = [a, [b, c,[d,e]]] 

和相應的樹是:

   a 
      /\ 
       b c 
       /\      
       d e 

每當有一個元素之後的子列表,該子列表對應於該元素的子節點。否則,元素位於同一圖層上。我想生成與每個節點作爲重點字典分別,如:

child[a] = [b,c,d,e] 
child[c] = [d,e] 

我如何能做到這一點在Python?或者還有其他更好的樹形結構轉換建議嗎?

+1

上的重複鍵會發生什麼,比如'[一,[b,a,[d,e]]]?結果是什麼樣的?嘗試使用樹的現有實現並使用它。 – 2014-12-11 01:01:02

+0

@ReutSharabani謝謝Reut。所有元素都是不同的。 – ChuNan 2014-12-11 01:18:42

回答

1

我仍然認爲你應該使用/獲取由現有實現的啓發,但是這可能是你在找什麼,如果你需要這個工作:

#!/usr/bin/env python 

# added a test case 
B = ['a', ['b', 'c',['d','e']], 'f', ['g', 'h']] 
A = ['a', ['b', 'c',['d','e']]] 

# found on stack overflow - flatten list of kids for parent 
def flatten(iterable): 
    """Recursively iterate lists and tuples. 
    """ 
    for elm in iterable: 
     if isinstance(elm, (list, tuple)): 
      for relm in flatten(elm): 
       yield relm 
     else: 
      yield elm 

# add data to an existing tree (recursive) 
def treeify(tree, l): 
    if isinstance(l, list): 
     # avoid looking back 
     l.reverse() 
    for index in range(len(l)): 
     if isinstance(l[index], list): 
      parent_name = l[index+1] 
      # flatten kids to a list 
      tree[parent_name] = list(flatten(l[index])) 
      # continue in deeper lists 
      treeify(tree, l[index]) 

tree = {} 
treeify(tree, A) 
print tree 
tree = {} 
treeify(tree, B) 
print tree 

這種反轉list避免回頭遍歷它時。如果當前的成員是list,則Tt將該名稱設置爲下一個成員,並立即遍歷子元素(遞歸)。

2

如果你要做很多圖表操作,我會考慮導入networkx,因爲它會讓事情變得更簡單。爲了解析您的嵌套列表爲networkx樹:

import networkx as nx 

def parse_tree(node_list): 
    """Parses a nested list into a networkx tree.""" 
    tree = nx.DiGraph() 
    root = node_list[0] 
    tree.add_node(root) 

    queue = [(root, node_list[1])] 

    while queue: 
     parent, nodes = queue.pop(0) 
     prev = None 
     for node in nodes: 
      if isinstance(node, list): 
       queue.append((prev, node)) 
      else: 
       tree.add_node(node) 
       tree.add_edge(parent, node) 

      prev = node 

    return tree 

有了這個功能,就可以輕鬆獲取每個節點的後代的字典:

>>> l = ["a", ["b", "c",["d","e"]]] 
>>> tree = parse_tree(l) 
>>> {node: nx.descendants(tree, node) for node in tree} 
{'a': {'b', 'c', 'd', 'e'}, 
'b': set(), 
'c': {'d', 'e'}, 
'd': set(), 
'e': set()}