5

我有一个这样的列表列表

matches = [[['rootrank', 'Root'], ['domain', 'Bacteria'], ['phylum', 'Firmicutes'], ['class', 'Clostridia'], ['order', 'Clostridiales'], ['family', 'Lachnospiraceae'], ['genus', 'Lachnospira']], 
           [['rootrank', 'Root'], ['domain', 'Bacteria'], ['phylum', '"Proteobacteria"'], ['class', 'Gammaproteobacteria'], ['order', '"Vibrionales"'], ['family', 'Vibrionaceae'], ['genus', 'Catenococcus']], 
           [['rootrank', 'Root'], ['domain', 'Archaea'], ['phylum', '"Euryarchaeota"'], ['class', '"Methanomicrobia"'], ['order', 'Methanomicrobiales'], ['family', 'Methanomicrobiaceae'], ['genus', 'Methanoplanus']]]

我想从它们中构建一个系统发育树。我写了一个这样的节点类(部分基于此代码):

class Node(object):
    """Generic n-ary tree node object
    Children are additive; no provision for deleting them."""

    def __init__(self, parent, category=None, name=None):
        self.parent = parent
        self.category = category
        self.name = name
        self.childList = []

        if  parent is None:
            self.birthOrder  =  0
        else:
            self.birthOrder  =  len(parent.childList)
            parent.childList.append(self)

    def fullPath(self):
        """Returns a list of children from root to self"""
        result  =  []
        parent  =  self.parent
        kid     =  self

        while parent:
            result.insert(0, kid)
            parent, kid  =  parent.parent, parent

        return result

    def ID(self):
        return '{0}|{1}'.format(self.category, self.name)

然后我尝试像这样构建我的树:

node = None
for match in matches:
    for branch in match:
        category, name = branch
        node = Node(node, category, name)
        print [n.ID() for n in node.fullPath()]

这适用于第一场比赛,但是当我从第二场比赛开始时,它会附加在树的末尾,而不是从顶部重新开始。我该怎么做?我尝试了一些搜索 ID 的变体,但无法正常工作。

4

3 回答 3

3

我强烈推荐使用像Dendropy这样的系统发育库。

'编写系统发育树的标准方法是使用 Newick 格式(括号语句,如 ((A,B),C))。如果你使用 Dendropy,读取那棵树就像

>>> import dendropy
>>> tree1 = dendropy.Tree.get_from_string("((A,B),(C,D))", schema="newick")

或从流中读取

>>> tree1 = dendropy.Tree(stream=open("mle.tre"), schema="newick")

该库的创建者也维护了一个不错的教程

于 2013-08-08T19:48:07.797 回答
2

问题是它node始终是树中最底部的节点,并且您始终附加到该节点。您需要存储根节点。由于['rootrank', 'Root']出现在每个列表的开头,我建议将其拉出并将其用作根。因此,您可以执行以下操作:

rootnode = Node(None, 'rootrank', 'Root')
for match in matches:
    node = rootnode
    for branch in match:
        category, name = branch
        node = Node(node, category, name)
        print [n.ID() for n in node.fullPath()]

这将使matches列表更具可读性,并提供预期的输出。

于 2013-08-08T14:24:25.263 回答
1

帮自己一个忙,不要重新发明轮子。Python-graph(又名 pygraph)完成了您在此处提出的所有要求以及接下来您将提出的大部分要求。

于 2013-08-08T14:32:18.380 回答