Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better equivalent of this crazy nested python for loop

for a in map:
    for b in map[a]:
        for c in map[b]:
            for d in map[c]:
                for e in map[d]:
                    print a+b+c+d+e

The above code is used to create all paths of certain length in a graph. map[a] represents the points you can reach from point a.

How can I change it to simulate having an arbitrary number of loops?

This is like a cartesian product (itertools.product) where at each iteration your choice for the next element is limited to those in map[current_point].

like image 291
Babak Avatar asked Jan 18 '12 06:01

Babak


3 Answers

map = {
    'a': ['b', 'c'],
    'b': ['c', 'd'],
    'c': ['d', 'a'],
    'd': []
}

def print_paths(map, start, length, prefix = ''):
    if length == 0:
        print prefix
    else:
        for a in map[start]:
            print_paths(map, a, length - 1, prefix + start)

for a in map.keys():
    print_paths(map, a, 5)
like image 105
Baffe Boyois Avatar answered Nov 15 '22 16:11

Baffe Boyois


This is a classical recursive problem. Your function should returns concatenation of node value with all results of your function result for each child node. As you can see in sentence, function behavior is explained in a recursive way:

myGraph = { 1:[2,3], 2:[3,4] }

def recorre( node_list, p = '' ):    
    for node in node_list:
        if node in myGraph and myGraph[node]: 
            recorre(myGraph[node], p+unicode( node ))
        else:
            print p+unicode( node )

recorre( myGraph )

Result:

>>> recorre( myGraph )
123
124
13
23
24

This code is a start point. You can store all paths in a list, use yield generator, etc. Don't forget to prevent circles.

Also, take a look to igraph solution. Sure this library can helps to you, see this example: Finds all shortest paths (geodesics) from a vertex to all other vertices.

Regards.

like image 28
dani herrera Avatar answered Nov 15 '22 16:11

dani herrera


Just like other suggested, with recursion:

    distances = []        

    def compute_distance(map, depth, sum):
         if depth == 0 or len(map) == 0:
            distances.append[sum]
         else:
            for a in map:
               compute_distance(map[a], depth - 1, sum + a)

   compute_distance(map, x, 0)
like image 39
Bogdan Avatar answered Nov 15 '22 17:11

Bogdan