Sean
Sean

Reputation: 1313

Python For...loop iteration

Alright, I have this program to sparse code in Newick Format, which extracts both a name, and a distance for use in a phylogenetic tree diagram. What my problem is, in this branch of code, as the program reads through the newickNode function, it assigns the name and distance to the 'node' variable, then returns it back into the 'Node' class to be printed, but it seems to only print the first node 'A', and skips the other 3.
Is there anyway to finish the for loop in newickNode to read the other 3 nodes and print them accordingly with the first?

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()

Thanks!

Upvotes: 1

Views: 513

Answers (5)

kindall
kindall

Reputation: 184081

Your newickNode() function should accumulate a list of nodes and return that, rather than returning the first node created. If you're going to do that, why have a loop to begin with?

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

Alternatively, you could write it as a generator that yields the nodes one at a time. This would allow you to easily iterate over them or convert them to a list depending on your needs.

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

Also, from a object-oriented design POV, this should probably be a class method on your Node class named parseNewickString() or similar.

Upvotes: 3

Jon Clements
Jon Clements

Reputation: 142106

To keep this more flexible - I would use pyparsing to process the Newick text and networkx so I had all the graph functionality I could desire - recommend to easy_install/pip those modules. It's also nice that someone has written a parser with node and tree creation already (although it looks like it lacks some features, it'll work for your case):

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

Upvotes: 1

jdi
jdi

Reputation: 92559

You could make it a generator:

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()

The generator will return one node at a time and pause within the function, and then resume when you want the next one.

Or just save them up and return them

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

Upvotes: 5

Daniel Roseman
Daniel Roseman

Reputation: 599480

Alternatively, your newickNode() function could immediately call node.displayNode() on the new node each time through the loop.

Upvotes: 1

Wooble
Wooble

Reputation: 89847

The first time through your for: loop, you return a node, which stops the function executing.

If you want to return a list of nodes, create the list at the top of the function, append to it each time through the loop, and return the list when you're done.

It may make more sense to move the loop outside of the newickNode function, and have that function only return a single node as its name suggests.

Upvotes: 0

Related Questions