Find all the paths through the tree (nested dictations) from top to bottom

EDIT: Below is the recommended answer and how it is still not quite right.

There are many similar questions in Qaru, but none of them are similar to Python. I'm starting to program, so please come through.

I have a tree of nested dictionaries, for example:

[{'word': 'The', 'next': [{'word': 'End', 'next': None}, {'word': 'quick', 'next': [{'word': 'brown', 'next': [{'word': 'fox', 'next': None}]}]}, {'word': 'best', 'next': [{'word': 'of', 'next': [{'word': 'times', 'next': None}]}]}]}] 

I want to smooth all the paths from top to bottom and in the end:

 [[{'word': 'The'}, {'word': 'End'}], [{'word': 'The'}, {'word': 'quick'}, {'word': 'brown'}, {'word': 'fox'}], [{'word': 'The'}, {'word': 'best'}, {'word': 'of'}, {'word': 'times'}]] 

I made a small recursive function that initially created the original structure, but it's hard for me to overdo it. This, as I understand it:

 def flatten_combinations(result_tree, current_combo = None, all_combos = None): if current_combo is None: current_combo = [] if all_combos is None: all_combos = [] if result_tree is None: all_combos.append(current_combo) return for word in result_tree: current_combo.append({'word': word['word']}) flatten_combinations(word['next'], current_combo, all_combos) return current_combo 

... which returns this:

 [{'word': 'The'}, {'word': 'End'}, {'word': 'quick'}, {'word': 'brown'}, {'word': 'fox'}, {'word': 'best'}, {'word': 'of'}, {'word': 'times'}] 

... which is clearly somewhat close, but not quite right.

I know that the function is probably terribly non-neat, but I teach myself programming, so I’m not even trying to use possibly existing language functions that would allow me to overcome thoughts through this material from scratch ("he said, sending Q & A to the site A in the hope that his members will help him figure it out a bit. "

So: what am I doing wrong?

EDIT : Moshe below fixed a couple of problems:

 def flatten_combinations(result_tree, current_combo = None, all_combos = None): if current_combo is None: current_combo = [] if all_combos is None: all_combos = [] if result_tree is None: all_combos.append(current_combo) return for word in result_tree: current_combo = current_combo[:] current_combo.append({'word': word['word']}) flatten_combinations(word['next'], current_combo, all_combos) return all_combos 

This is even closer, but not entirely correct:

 [{'word': 'The'}, {'word': 'End'}], [{'word': 'The'}, {'word': 'End'}, {'word': 'quick'}, {'word': 'brown'}, {'word': 'fox'}], [{'word': 'The'}, {'word': 'End'}, {'word': 'quick'}, {'word': 'best'}, {'word': 'of'}, {'word': 'times'}]] 
+6
source share
4 answers

There are two minor errors in this:

1) Instead of all_combos you return current_combo . This gives you the last result.

2) At each iteration, you change current_combo . Make a copy first!

 new_current_combo = current_combo[:] new_current_combo.append({'word': word['word']}) flatten_combinations(word['next'], new_current_combo, all_combos) 

Full code:

 def flatten_combinations(result_tree, current_combo=None, all_combos=None): if current_combo is None: current_combo = [] if all_combos is None: all_combos = [] if result_tree is None: all_combos.append(current_combo) return for word in result_tree: new_current_combo = current_combo[:] new_current_combo.append({'word': word['word']}) flatten_combinations(word['next'], new_current_combo, all_combos) return all_combos 
+1
source

If you pass a copy of current_combo to a recursive call, you won't lose your current path in the next iteration of the for loop.

In addition, you do not need to return current_combo, since the result is not used in recursion. You might want to return all_combos and not accept it as a parameter. Alternatively, you can have a recursive function and not have any recursive function, with the non-recursive function creating a list for all_combos and passing it to the recursive function so that the recursive function can assume that all_combos is set.

+1
source

I would take this strategy: for each tree

  • Recurse to calculate the list of sentences that come after the word in the root of this tree.
  • For each sentence, add the current word in front of it.
  • Returns an extended list of offers.

Have you made evidence by induction? I consider induction to be one of the most useful mathematical techniques in my programming:

  • Prove that your function handles the tree correctly, where "next" is None .
  • Prove that your function processes the tree of depth n , assuming that it can correctly process the tree of depth n-1 .

Then induction extends the proof to cover trees of any depth. Done!

+1
source

Just forcing @JoshHeitzman to answer specific (and simplifying your default options):

 def flatten_combinations(result_tree, current_combo = [], all_combos = []): if result_tree is None: all_combos.append(current_combo) return for word in result_tree: current_combo.append({'word': word['word']}) flatten_combinations(word['next'], current_combo[:], all_combos) return all_combos 
0
source

All Articles