0

Is there any way you could pass dict positions of variable length to a function?

def change_settings(val: str, new_data: Union[str, int, dict]):
    with open('somefile.json') as f:
        data = json.load(f)
    with open('somefile.json', 'w') as f:
        data[val] = new_data
        json.dump(config, f, indent=4)

Something like this, however this doesn't allow for changing a sub dictionary like for example [val1][val2]

AvidProgrammer
  • 103
  • 2
  • 8

1 Answers1

0

I coded this function change_settings_deep which can take a deeper key (e.g. [key1, key2]) as argument to change your value. BTW I also fixed an error in your original function that would lead to a ValueError: Circular reference detected.

import json
from typing import Union, List

def change_settings(key: str, val: Union[str, int, dict]):
    with open('somefile.json') as f:
        data = json.load(f)
    with open('somefile.json', 'w') as f:
        data[key] = val
        json.dump(data, f, indent=4)

# {"a": {"b": 7}, "c": 9}
change_settings('c', 'lol')
# {"a": {"b": 7}, "c": "lol"}

def change_settings_deep(keys: List[str], val: Union[str, int, dict]):
    with open('somefile.json') as f:
        data = json.load(f)
    with open('somefile.json', 'w') as f:
        data_cur = data
        for key in keys[:-1]:
            data_cur = data_cur[key]
        data_cur[keys[-1]] = val
        json.dump(data, f, indent=4)

# {"a": {"b": 7}, "c": 9}
change_settings_deep(['c'], 'bruh')
# {"a": {"b": 7}, "c": "lol"}
change_settings_deep(['a', 'b'], 'magic')
# {"a": {"b": "magic"}, "c": "bruh"}
xjcl
  • 12,848
  • 6
  • 67
  • 89
  • Thanks! I was clearly close to your solution as well, I did the same thing of storing the data in a new var and looping over the keys and changing that new var, but didnt know how to actually change the data in the end. – AvidProgrammer Mar 13 '21 at 11:50