Here's a quick hack - I'm sure it can be shortened.
def find_value(idx: str, data: dict):
field_name = idx.split('.')[0]
if field_name in data:
value = data[field_name]
if isinstance(value, dict) and len(idx.split('.')) > 0:
return find_value(idx='.'.join(idx.split('.')[1:]), data=value)
else:
return value
raise Exception('Key "{}" not found'.format(idx))
def replace_value(idx: str, data: dict, new_value, _new_data: dict=dict()):
field_name = idx.split('.')[0]
if field_name in data:
value = data[field_name]
if isinstance(value, dict) and len(idx.split('.')) > 0:
new_dict = {**_new_data, **replace_value(idx='.'.join(idx.split('.')[1:]), data=value, new_value=new_value) }
return {**_new_data, **{ field_name: new_dict} }
else:
return {**_new_data, **{ field_name: new_value} }
raise Exception('Key "{}" not found'.format(idx))
if __name__ == '__main__':
data = {'person': {'name': 'test_user',}}
index = 'person.name'
print('Value pre-processing : {}'.format(find_value(idx=index, data=data)))
data = replace_value(idx=index, data=data, new_value='test_user_2')
print('Value post-processing : {}'.format(find_value(idx=index, data=data)))
print('data : {}'.format(data))
The output when run:
$ python3 test.py
Value pre-processing : test_user
Value post-processing : test_user_2
data : {'person': {'name': 'test_user_2'}}