1

好的,我有这个程序以 Newick 格式稀疏代码,它提取名称和距离以用于系统发育树图中。我的问题是,在这个代码分支中,当程序读取 newickNode 函数时,它将名称和距离分配给“节点”变量,然后将其返回到“节点”类以进行打印,但似乎只打印第一个节点'A',并跳过其他3个。
无论如何要完成newickNode中的for循环以读取其他3个节点并与第一个节点相应地打印它们?

class Node:
    def __init__(self, name, distance, parent=None):
        self.name = name
        self.distance = distance
        self.children = []  
        self.parent = parent

    def displayNode(self):
        print "Name:",self.name,",Distance:",self.distance,",Children:",self.children,",Parent:",self.parent

def newickNode(newickString, parent=None):
    String = newickString[1:-1].split(',')
    for x in String:
        splitString = x.split(':')
        nodeName = splitString[0]
        nodeDistance = float(splitString[1]) 
        node = Node(nodeName, nodeDistance, parent)
        return node

Node1 = newickNode('(A:0.1,B:0.2,C:0.3,D:0.4)')
Node1.displayNode()

谢谢!

4

5 回答 5

5

你可以把它变成一个生成器:

def newickNode(newickString, parent=None):
    String = newickString[1:-1].split(',')
    for x in String:
        splitString = x.split(':')
        nodeName = splitString[0]
        nodeDistance = float(splitString[1]) 
        node = Node(nodeName, nodeDistance, parent)
        yield node

for node in newickNode('(A:0.1,B:0.2,C:0.3,D:0.4)'): 
    node.displayNode()

生成器将一次返回一个节点并在函数内暂停,然后在您需要下一个节点时恢复。

或者只是保存它们并返回它们

def newickNode(newickString, parent=None):
    String = newickString[1:-1].split(',')
    nodes = []
    for x in String:
        splitString = x.split(':')
        nodeName = splitString[0]
        nodeDistance = float(splitString[1]) 
        node = Node(nodeName, nodeDistance, parent)
        nodes.append(node)
    return nodes
于 2012-06-25T18:52:36.790 回答
3

您的newickNode()函数应该累积节点列表并返回它,而不是返回创建的第一个节点。如果您要这样做,为什么要从一个循环开始?

def newickNodes(newickString, parent=None):
    nodes = []
    for node in newickString[1:-1].split(','):
        nodeName, nodeDistance = node.split(':')
        nodes.append(Node(nodeName, nodeDistance, parent))
    return nodes

或者,您可以将其编写为一次生成一个节点的生成器。这将允许您根据需要轻松迭代它们或将它们转换为列表。

def newickNodes(newickString, parent=None):
    for node in newickString[1:-1].split(','):
        nodeName, nodeDistance = node.split(':')
        yield Node(nodeName, nodeDistance, parent)

此外,从面向对象的设计 POV 来看,这可能应该是您的Node类上命名parseNewickString()或类似的类方法。

于 2012-06-25T18:51:23.250 回答
1

为了保持更灵活——我会用它pyparsing来处理 Newick 文本,networkx所以我拥有我想要的所有图形功能——推荐给easy_install/pip那些模块。有人已经编写了具有节点和树创建的解析器也很好(尽管它看起来缺少一些功能,但它适用于您的情况):

http://code.google.com/p/phylopy/source/browse/trunk/src/phylopy/newick.py?r=66

于 2012-06-25T19:07:14.103 回答
1

或者,您的函数可以在每次循环时newickNode()立即调用新节点。node.displayNode()

于 2012-06-25T18:52:11.083 回答
0

第一次通过你的for:循环,你return是一个节点,它会停止函数的执行。

如果要返回节点列表,请在函数顶部创建列表,每次通过循环附加到它,并在完成后返回列表。

将循环移到函数之外可能更有意义newickNode,并让该函数如其名称所示仅返回单个节点。

于 2012-06-25T18:51:30.410 回答