0

I have a dictionary with id and multiple values for each ID which are strings. For each value in that for each Id I make a database query and get set results:

{111: Run, Jump, swim}
{222: Eat, drink}

so for each value lets say run I execute a query and it returns another set of data then pick each value of that set and run query which will give another set and finally I come to a point where there is only one item get return. Once I finish get that final element of every single sub element of Run then I move to Jump and continue.

I asked this question before but didn't get any results so people told me to remove the code and just ask the question again. Here is the link for the same question which I ask few days ago. Do i need to implement something like disjoin set?

Community
  • 1
  • 1
add-semi-colons
  • 18,094
  • 55
  • 145
  • 232

2 Answers2

2

You can look at the categories/subcategories as a tree with N branches at each node (depending how many categories you have). From what I can gather you basically want to generate an in-order list of tree leaves.

One simple way of doing it is through generators (using the terminology from your original question):

def lookup(elem):
    # do your SQL call here for a given category 'elem' and return
    # a list of it's subcategories
    return []

def leaves(lst):
    if lst:
        for elem in lst:                          # for every category
            for sublist in leaves(lookup(elem)):  # enumerate it's sub categories
                yield sublist                     # and return it
            yield elem                            # once lookup(elem) is [] return elem

d = { 111: [Run, Jump, swim] , 222: [Eat, drink] }

for key, lst in d.items():
    print key, [elem for elem in leaves(lst)]

If you are unfamiliar with generators, they are simply iterator constructs that "yield" values instead of returning them. The difference is that yielding only pauses the iterator at that location which will continue where it stopped when the next value is requested.

With some clever recursion inside the generator you can simply parse the whole tree.

The [elem for elem in leaves(lst)] is a list comprehension and it simply builds a list containing elem for every element iterated by leaves.

enticedwanderer
  • 4,346
  • 28
  • 24
  • Thanks alot I was wondering if you had a chance to take a look at my attempts in my original question which I put a link here..? – add-semi-colons Nov 09 '11 at 05:12
  • I am bit confuse with line where you have the dictionary and after that... any chance you could explain that..? I tried to run but it gives an error in square brackets. – add-semi-colons Nov 09 '11 at 05:28
  • 1
    Sorry, in the last line it should be print key, [elem for elem in inorder(lst)] Edited the code above – enticedwanderer Nov 09 '11 at 12:04
  • not sure if got a chance to take a look at my attempt which put it up in a different post (link). I was going to replace my recursive code with your method but I am bit confuse on how I store these values in a dictionary with the yield function that you have written here. – add-semi-colons Nov 10 '11 at 04:24
  • could you please explain this section, for key, lst in d.items(): print key, [elem for elem in leaves(lst)] based on your comment it says inorder but i am getting errors. Thanks – add-semi-colons Nov 18 '11 at 00:47
  • 1
    Code above should be correct now. It basically creates a list of leaves for each key and initial list say key=111 and lst=[Run, Jump, swim] should output "111 [RunLeaf1, RunLeaf2, RunLeaf3, JumpLeaf1, JumpLeaf2, SwimLeaf1, SwimLeaf2...]" "222 ..." so on – enticedwanderer Nov 18 '11 at 02:16
  • 1
    For instance provided that Run -> [ RunChild1, RunChild2, ...] and RunChild1 -> [RunLeaf1] and RunChild2 -> [RunLeaf2, RunLeaf3] and so on... – enticedwanderer Nov 18 '11 at 02:17
  • Thanks alot I actually used your code, it was much cleaner that my original recursion code but I am getting maximum recursion depth which I got in my original code and didn't change it even after i used your method. – add-semi-colons Nov 18 '11 at 02:33
  • my keys get printed fine but not the list values this is what i get as a print Prima_Vera-sanger [] EP-plater_fra_2002 [] – add-semi-colons Nov 18 '11 at 04:50
  • 1
    If you are getting maximum recursion depth then it looks like your data structure is not actually a tree and it might have back edges (a leaf points to some of its parents for example) in which case you may get into infinite loops in which case obviously this approach will not work and you will have to adapt. – enticedwanderer Nov 18 '11 at 13:05
0

This looks like plain tree traversal. You can use BFS or DFS.

Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95