Last active
June 13, 2018 22:53
-
-
Save Avantol13/2e82b897cd78009fcb917eb3c320db63 to your computer and use it in GitHub Desktop.
Replace nested value in dict from another nested value in a different dict
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import copy | |
def replace(data, path_to_key, replacement_value): | |
""" | |
Will replace a nested value in a dict with the given value. | |
Args: | |
data (dict): a dictionary | |
path_to_key (str): nested/path/to/key. The value of this key will be | |
replaced | |
replacement_value (str): Replacement value for the key from | |
path_to_key | |
""" | |
nested_path_to_replace = path_to_key.split('/') | |
# follow dict to final key | |
for item in nested_path_to_replace[:-1]: | |
data = data.get(item, {}) | |
data.update( | |
{str(nested_path_to_replace[-1]): replacement_value} | |
) | |
def get_nested_value(dictionary, nested_path): | |
""" | |
Return a value from a dictionary given a path-like nesting of keys. | |
Will default to an empty string if value cannot be found. | |
Args: | |
dictionary (dict): a dictionary | |
nested_path (str): nested/path/to/key | |
Returns: | |
?: Value from dict | |
""" | |
replacement_value_path = nested_path.split('/') | |
replacement_value = copy.deepcopy(dictionary) | |
for item in replacement_value_path: | |
replacement_value = replacement_value.get(item, {}) | |
if replacement_value == {}: | |
replacement_value = '' | |
return replacement_value |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import nested_dict_replace | |
def test_replace(): | |
data = { | |
'top-level': { | |
'second-level': { | |
'some_key': '12345', | |
'some_other_key': '54321', | |
'another-level': { | |
'nested_key': 'abc' | |
} | |
}, | |
'another-second-level': { | |
'some_key': 'def' | |
} | |
} | |
} | |
new_data = { | |
'level-1': { | |
'level-2': { | |
'level-3': { | |
'some_new_key': '67890', | |
'some_other_new_key': '09876' | |
} | |
} | |
} | |
} | |
replacement_key = nested_dict_replace.get_nested_value( | |
new_data, 'level-1/level-2/level-3/some_new_key') | |
nested_dict_replace.replace( | |
data, 'top-level/second-level/some_key', replacement_key) | |
assert ( | |
data['top-level']['second-level']['some_key'] | |
== new_data['level-1']['level-2']['level-3']['some_new_key'] | |
) | |
assert ( | |
data['top-level']['second-level']['some_other_key'] | |
== '54321' | |
) | |
assert ( | |
data['top-level']['second-level']['another-level']['nested_key'] | |
== 'abc' | |
) | |
assert ( | |
data['top-level']['another-second-level']['some_key'] | |
== 'def' | |
) | |
def test_replace_doesnt_exist(): | |
""" | |
Test that when the replacement value isn't there, we just insert an | |
empty string. | |
""" | |
data = { | |
'top-level': { | |
'second-level': { | |
'some_key': '12345', | |
'some_other_key': '54321', | |
'another-level': { | |
'nested_key': 'abc' | |
} | |
}, | |
'another-second-level': { | |
'some_key': 'def' | |
} | |
} | |
} | |
new_data = {} | |
replacement_key = nested_dict_replace.get_nested_value( | |
new_data, 'level-1/level-2/level-3/some_new_key') | |
nested_dict_replace.replace( | |
data, 'top-level/second-level/some_key', replacement_key) | |
assert ( | |
data['top-level']['second-level']['some_key'] | |
== '' | |
) | |
assert ( | |
data['top-level']['second-level']['some_other_key'] | |
== '54321' | |
) | |
assert ( | |
data['top-level']['second-level']['another-level']['nested_key'] | |
== 'abc' | |
) | |
assert ( | |
data['top-level']['another-second-level']['some_key'] | |
== 'def' | |
) | |
def test_nothing_to_replace(): | |
data = {} | |
new_data = { | |
'level-1': { | |
'level-2': { | |
'level-3': { | |
'some_new_key': '67890', | |
'some_other_new_key': '09876' | |
} | |
} | |
} | |
} | |
replacement_key = nested_dict_replace.get_nested_value( | |
new_data, 'level-1/level-2/level-3/some_new_key') | |
nested_dict_replace.replace( | |
data, 'top-level/second-level/some_key', replacement_key) | |
assert data == {} | |
if __name__ == '__main__': | |
test_replace() | |
test_replace_doesnt_exist() | |
test_nothing_to_replace() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment