Faster way to build a tree graph using Networkx Python?
Question: Is there any faster, nicer way of building a Networkx tree. Currently, my code
is

    
    
    for numb in range(0,len(previous)):
        nodos = list(chunks(current,3))
            for i in range(0,3):
                G.add_edge(previous[numb],nodos[numb][i])
    

This works in the following way: 1. The tree has 3 branches (or edges). I have
two arrays:

    
    
    previous = [x,y,z] #These nodes have already been added to the graph
    current = [xx,xy,xz, xy,yy,yz, xz,yz,zz] #This nodes need to be added.
    

Ideally, I should do the following:

    
    
    1. Start with x in previous:
    1.1 Pick the first 3 nodes in current (i.e. xx,xy,xz)
    1.1.1 Add the nodes-edges: x->xx, x->xy, x->xz
    

So far my codes does:

    
    
    1. Start with x in previous
    2. Partition current into chunks of 3 items: [[xx,xy,xz], [xy,yy,yz], [xz,yz,zz]]
    3. Loop through all the nodes in these chunks:
    4. Add x->xx, loop again, add x->xy... etc.
    

My implementation is extremely inefficient. How would you do this efficiently?
Thank you


Answer: You could use the helper function from
<https://github.com/networkx/networkx/blob/master/networkx/generators/classic.py#L50>

    
    
    def _tree_edges(n,r):
        # helper function for trees
        # yields edges in rooted tree at 0 with n nodes and branching ratio r
        nodes=iter(range(n))
        parents=[next(nodes)] # stack of max length r
        while parents:
            source=parents.pop(0)
            for i in range(r):
                try:
                    target=next(nodes)
                    parents.append(target)
                    yield source,target
                except StopIteration:
                    break
    
    print list(_tree_edges(13,3))
    #[(0, 1), (0, 2), (0, 3), (1, 4), (1, 5), (1, 6), (2, 7), (2, 8), (2, 9), (3, 10), (3, 11), (3, 12)]
    import networkx as nx
    G = nx.Graph(_tree_edges(13,3))
    

If you want nodes other than integers you can either relabel or specify them
on input like this

    
    
    def _tree_edges(nodes,r):
        # helper function for trees
        # yields edges in rooted tree with given nodes and branching ratio r
        nodes=iter(nodes)
        parents=[next(nodes)] # stack of max length r
        while parents:
            source=parents.pop(0)
            for i in range(r):
                try:
                    target=next(nodes)
                    parents.append(target)
                    yield source,target
                except StopIteration:
                    break
    
    nodes = list('abcdefghijklm')
    print list(_tree_edges(nodes,3))
    

