簡體   English   中英

如何將 Python 字典轉換為 Newick 表單格式?

[英]How to convert Python dictionary to Newick form format?

我有以下形式的 Python 字典:

{
    'a': {'leaf1': 12, 'leaf2': 32},
    'b': {'a': 2, 'leaf3': 21, 'leaf4': 3},
    'c': {'leaf5': 5, 'leaf6': 7}
}

其中'a' , 'b' , 'c'是內部節點, leaf1 ... leaf6是葉節點(沒有子節點), 12 , 32 , 2 , 21 , ... 7是分支長度給定的節點或子樹。

我需要將此字典轉換為 Newick 形式,以便使用外部應用程序繪制一棵樹。

紐威克格式:

(((leaf1:12,leaf2:32):2,leaf3:21, leaf4:3),leaf5:5,leaf6:7);

我寫了以下代碼,但沒有成功:

def get_newick(self,dic):      
        roots=[node for node,children in dic.items() if sum([1 if len(child)>1 else 0 for child in children.keys()])==len(children.keys())]                       
        nonrooted=[node for node,children in dic.items() if sum([1 if len(child)>1 else 0 for child in children.keys()])!=len(children.keys())]        
        dic1={}
        for subtree in nonrooted:
            patt=[]
            for child,v in dic[subtree].items():
                if child in roots:
                    patt.append(tuple(["%s:%d"%(k,v) for k,v in dic[child].items()]))
                    roots.remove(child)
                elif len(child)>1:
                    patt.append("%s:%d"%(child,v))
            dic1[subtree]=patt         

您處理問題的方式存在問題:在您的字典中,不清楚哪些節點位於頂層。 這是一個有效的解決方案:

def newickify(node_to_children, root_node) -> str:
    visited_nodes = set()

    def newick_render_node(name, distance: float) -> str:
        assert name not in visited_nodes, "Error: The tree may not be circular!"

        if name not in node_to_children:
            # Leafs
            return F'{name}:{distance}'
        else:
            # Nodes
            visited_nodes.add(name)
            children = node_to_children[name]
            children_strings = [newick_render_node(child, children[child]) for child in children.keys()]
            children_strings = ",".join(children_strings)
            return F'({children_strings}){name}:{distance}'

    newick_string = newick_render_node(root_node, 0) + ';'

    # Ensure no entries in the dictionary are left unused.
    assert visited_nodes == set(node_to_children.keys()), "Error: some nodes aren't in the tree"

    return newick_string


node_to_children = {
    'root': {'b': 3, 'c': 5},
    'a': {'leaf1': 12, 'leaf2': 32},
    'b': {'a': 2, 'leaf3': 21, 'leaf4': 3},
    'c': {'leaf5': 5, 'leaf6': 7}
}

print(newickify(node_to_children, root_node='root'))

這是輸出的樣子:

(((leaf1:12,leaf2:32)a:2,leaf3:21,leaf4:3)b:3,(leaf5:5,leaf6:7)c:5)root:0;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM