0

I need to update the value in a nested dictionary, however I have a list with all of the keys that I need to go through in order to get tot hat value. However this list is automatically generated and the number of layers is not always the same.

Example Dictionary:

{'pop_up_message': {'': []}, 'widgets': {'separator_dropdown': {'widget': '', 'location': {'columnspan': 1, 'row': 0, 'column': 11, 'sticky': 'e', 'rowspan': 1}, 'selected_option': '', 'position': 5}, 'go': {'widget': '', 'location': {'columnspan': 1, 'row': 0, 'column': 6, 'sticky': 'nsew', 'rowspan': 1}, 'position': 4}, 'middle_label': {'widget': '', 'type': 'label', 'location': {'columnspan': 2, 'row': 1, 'column': 5, 'sticky': 'nsew', 'rowspan': 1}, 'default_name': 'Translated File', 'position': 7}, 'export': {'widget': '', 'location': {'columnspan': 2, 'row': 0, 'column': 5, 'sticky': 'nsew', 'rowspan': 1}, 'default_name': 'Export to .txt', 'position': 10}, 'quit': {'widget': '', 'location': {'columnspan': 1, 'row': 1, 'column': 1, 'sticky': 'nsew', 'rowspan': 1}, 'position': 9}, 'separator_message': {'widget': '', 'type': 'label', 'location': {'columnspan': 1, 'row': 0, 'column': 11, 'sticky': 's', 'rowspan': 1}, 'default_name': 'Define Separator', 'position': 2}, 'output_table': {'height': 25, 'position': 8, 'widget': '', 'type': 'scroll_text', 'location': {'columnspan': 11, 'row': 1, 'column': 1, 'sticky': 'nsew', 'rowspan': 1}, 'default_state': 'disabled'}, 'input_table': {'height': 10, 'position': 6, 'widget': '', 'type': 'scroll_text', 'location': {'columnspan': 11, 'row': 1, 'column': 1, 'sticky': 'nsew', 'rowspan': 1}, 'default_state': 'normal'}, 'import_file': {'widget': '', 'location': {'columnspan': 2, 'row': 1, 'column': 4, 'sticky': 'nsew', 'rowspan': 1}, 'position': 3}, 'clear': {'widget': '', 'location': {'columnspan': 1, 'row': 0, 'column': 11, 'sticky': 'nsew', 'rowspan': 1}, 'position': 11}, 'input_message': {'widget': '', 'type': 'label', 'location': {'columnspan': 2, 'row': 1, 'column': 5, 'sticky': 'nsew', 'rowspan': 1}, 'default_name': 'Insert / Import FIX Message', 'position': 1}}, 'tab_restriction': 'EMC', 'name': 'FIX Translator'}

List of keys:

['widgets', 'separator_dropdown', 'location', 'row']

Value to change: from 0 to 3

I have a nested dictionary (which I read from a JSON file). this contains a config for a Tkinter application. Using Tkinter I have built an interface where I can read the configs and display it on a frame where dict keys are tk. Labels and dict values are tk.Entry.

The idea is that I can update (entry widgets) the interface and when pull all of the data from the entry widgets and update the JSON file

Now, I have a list of tk. Entry with values and the associated "path" in the dictionary and now need to update that dictionary and save it as JSON.

Tai Kamilla
  • 43
  • 1
  • 9
zendek
  • 24
  • 3
  • yes, [this answer](https://stackoverflow.com/questions/13687924/setting-a-value-in-a-nested-python-dictionary-given-a-list-of-indices-and-value) is what I wanted to post –  Jul 16 '19 at 14:43
  • @reportgunner Given that it's a duplicate vote to close as duplicate instead. The older question already has 4-5 different solutions that handle corner cases etc differently so it seems to be pretty exhaustive – Giacomo Alzetta Jul 16 '19 at 14:45
  • I did @GiacomoAlzetta, but wanted to also point the user to a specific answer. –  Jul 16 '19 at 14:46

1 Answers1

2

You can get and set from the dictionary using recursion:

def getNestedItem(dictionary, path):
    if len(path) > 1:
        return getNestedItem(dictionary[path[0]], path[1:])
    else:
        return dictionary[path[0]]

def setNestedItem(dictionary, path, value):
    if len(path) > 1:
        setNestedItem(dictionary[path[0]], path[1:], value)
    else:
        dictionary[path[0]] = value

You can save a dictionary using the json module

import json
jsonData = json.dumps(dictionary)
with open("output.json", "w"):

Jmonsky
  • 1,519
  • 1
  • 9
  • 16