Find all paths through a tree (nested dicts) from top to bottom

2024/9/20 19:18:04

EDIT: See below for a suggested answer and how it's not quite right yet.

There are many similar questions to this one on Stack Overflow, but none exactly like it in Python. I'm a programming novice, so please go easy.

I have a tree of nested dictionaries, like this:

[{'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 flatten all paths from top to bottom and end up with this:

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

I made a lovely little recursive function that created the original structure in the first place, but I'm having a hard time unrecursivizing it. This is as far as I got:

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)returnfor 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 function is probably horribly un-Pythonic, but I'm teaching myself programming, so I'm not even trying to take advantage of possibly-existent language features that would let me elide over thinking through this stuff from scratch (” he said, posting to a Q&A site in the hope its members would help him elide a bit of thought).

So: what am I doing wrong?

EDIT: Moshe below corrected 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)returnfor 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 closer yet, but not quite right:

[{'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'}]]
Answer

There are two minor mistakes in that:

1) You return current_combo instead of all_combos. That only gives you your last result

2) On each iteration, you modify 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)returnfor 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 
https://en.xdnf.cn/q/72068.html

Related Q&A

How to show process state (blocking, non-blocking) in Linux

Is there a way to query the state of processes in a Linux process table to be able to demonstrate if a process is running or blocked at the time the query is executed? My goal is to do this from outsi…

Removing quotation marks from list items

I am running this program:f = open( "animals.txt", "r") g = f.read() g1 = g.split(,) #turning the file into list print g1And I want this to come out:[ELDEN, DORSEY, DARELL, BRODERIC…

Handle multiple questions for Telegram bot in python

Im programming a telegram bot in Python using the Telegram bot API. Im facing the problem of managing questions that need an answer of the user. The problem arises when the program is waiting for an an…

Which GTK+ elements support which CSS properties?

While applying my own CSS to my GTK+ application, I noticed, that some elements ignore some CSS properties and others ignore others or dont ignore them, which leads me to search for an overview of whic…

Self import of subpackages or not?

Suppose you have the following b b/__init__.py b/c b/c/__init__.py b/c/d b/c/d/__init__.pyIn some python packages, if you import b, you only get the symbols defined in b. To access b.c, you have to exp…

why is my text not aligning properly in wxPython?

Im using wxPython to build a GUI and Im trying to align some text but its not working at all. Im trying align three different static text items in three places (right aligned, center aligned, and left …

Python subprocess check_output decoding specials characters

Im having some issues with python encoding. When I try to execute this:subprocess.check_output("ipconfig", shell=True)it gives me an output with special characters in it, like:"Statut du…

Python - SystemError: NULL result without error in PyObject call

The story: Im trying to interface from C to Python in order to use the faster computational speed of C for an existing Python code. I already had some success, also with passing NumPy arrays - but now …

Fix jumping of multiple progress bars (tqdm) in python multiprocessing

I want to parallelize a task (progresser()) for a range of input parameters (L). The progress of each task should be monitored by an individual progress bar in the terminal. Im using the tqdm package f…

How to access data stored in QModelIndex

The code below create a single QListView with the data and proxy models "attached". Clicking one of the radio buttons calls for buttonClicked() function. This function calls models .data(inde…