我有一个像这样的列表列表
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']]]
我想从它们构建一个系统发育树。我写了一个像这样的节点类(部分基于this code):
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的变体,但我无法让它工作。
答案 0 :(得分: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
列表更具可读性,并提供预期的输出。
答案 1 :(得分:2)
我强烈建议使用像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")
图书馆的创建者也保持了良好的tutorial。
答案 2 :(得分:1)
帮自己一个忙,不要重新发明轮子。 Python-graph (a.k.a. pygraph)完成了你在这里提出的所有问题以及接下来要问的大部分事情。