7

I have a dictionary with the following structure:

 KEY    VALUES
 v1 = {v2, v3}
 v2 = {v1}
 v3 = {v1, v5}
 v4 = {v10}
 v5 = {v3, v6}

The values of a key are actually links to other keys. By using the values I want to reach the other keys till the end. Some keys are not linked as you can see for v4. I think this is similar to graph traversal?


enter image description here

starting from v1 I want to travel to all the other values:

v1 --> v2 --> v1
   --> v3 --> v1
          --> v5 --> v3
                 --> v6      
v4 --> v10 

def travel():
  travel_dict = defaultdict(list)
  travel_dict[v1].append(v2)
  travel_dict[v1].append(v3)
  travel_dict[v2].append(v1)
  travel_dict[v3].append(v1)
  travel_dict[v3].append(v5)
  travel_dict[v5].append(v3)
  travel_dict[v5].append(v6)
  travel_dict[v6].append(v5)
  travel_dict[v4].append(v10)

What Recursive function can I use to travel the dictionary?

Hani Goc
  • 2,371
  • 5
  • 45
  • 89

2 Answers2

5

A simple solution is to keep a "visited" set of already known nodes:

def reach(travel_dict, x, visited=None):
    if visited is None:
        visited = set() # see note
    visited.add(x)
    for y in travel_dict.get(x, []):
        if y not in visited:
            yield y
            for z in reach(travel_dict, y, visited):
                yield z

used as

for y in reach(travel_dict, x):
    print("you can go to", y)

NOTE: The only tricky part is that default arguments in Python are evaluated when creating the function object and not when the function is called, therefore using mutable defaults is a problem because changes will remain in effect after the function returns.

6502
  • 112,025
  • 15
  • 165
  • 265
  • 1
    Really Interesting Sorry. It took some time to test it on the dataset. I was able to traverse all the nodes the correctly. @6502 would you have stored the data in a graph and did a graph traversal instead of a dictionary? or is it in fact the same? – Hani Goc Nov 06 '15 at 11:19
  • 2
    @HaniGoc: a graph is an abstract data structure that can be represented in a few ways... one of them is a dictionary of lists (but you could have used for example objects containing a `links` list as one of the members). What is better depends on many factors (if you care more about speed or about size, what kind of query you need to do, if the graph is static or dynamic...). – 6502 Nov 06 '15 at 11:26
0

Here's one way: This recursively simplifies each element to a string form before it returns it..This should serve as a good starting point for you

def traverse(obj):
    '''
    stringify individual elems of an object where object can be a nested structure
    '''
    if isinstance(obj, dict):
        return dict((str(k),traverse(v)) for k,v in obj.items())
    else:
        return str(obj)  # no container, just values (str, int, float)
labheshr
  • 2,858
  • 5
  • 23
  • 34