Skip to content

Instantly share code, notes, and snippets.

@Avantol13
Last active June 13, 2018 22:53
Show Gist options
  • Save Avantol13/2e82b897cd78009fcb917eb3c320db63 to your computer and use it in GitHub Desktop.
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
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
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