nestdictutils#
- utils.recursive_add(d, key_path, in_place=False)#
Recursively add to a dictionary from a “key path” (= sequence of keys) and the associated value.
- Parameters:
- d
dict Input dictionary.
- key_path
tuple The “key path” and the associated value.
- in_place
bool, default:False Whether to modify the input dictionary in place or return a new dictionary.
- d
- Returns:
dictorNoneEither a new dictionary (if
in_placeisFalse) orNone(ifin_placeisTrue).
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Add an element to the {7:8} inner dictionary and return # a new dictionary >>> new_d = nestdictutils.recursive_add(d, ((6, 3, 12), 13), False) >>> new_d {1: 2, 3: {4: 5}, 6: {3: {7: 8, 12: 13}, 7: 10}, 7: 11}
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Try to add a new element associated with key 7 in the # {7:8} inner dictionary >>> new_d = nestdictutils.recursive_add(d, ((6, 3, 7, 12), 13), False) You cannot add element '13' at position (6, 3, 7, 12) because at least one key in the path is not associated with a dictionary. >>> new_d {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11}
- utils.recursive_build(key_paths)#
Recursively build a dictionary from “key paths” (= sequence of keys) and their associated values.
- Parameters:
- key_pathsany iterable of “key paths”
The “key paths”.
- Returns:
dictThe dictionary built from the “key paths”.
Examples
# Define the key paths >>> key_paths = (((1,2),3), ((4,),5)) # Build the dictionary >>> d = nestdictutils.recursive_build(key_paths) >>> d {1: {2: 3}, 4: 5}
# Define the key paths >>> key_paths = (((1,2),3), ((4,),5), ((4,),6)) # Build the dictionary >>> d = nestdictutils.recursive_build(key_paths) >>> d {1: {2: 3}, 4: 6} You provided several instances of the key path ((4,)). Only ((4,), 5) will be used when building the dictionary.
- utils.recursive_filter_dict(d, func, keys=None, in_place=False, permissive=False)#
Recursively filter a dictionary’s values. Only values for which the filter
funcreturnsTruewill be kept, while the others (together with their associated keys) will be removed from the dictionary.- Parameters:
- d
dict The input dictionary.
- funcany callable
Filtering callable taking as inputs the leaf values in the dictionary and returning
TrueorFalse.- keys
list,set, optional List of specific keys on whose values the filtering should be performed. This means that all values associated with keys different from those in the list will not be affected. If
None, all keys and associated values will be considered.- in_place
bool, default:False Whether to modify the input dictionary in place or return a new dictionary.
- permissive
bool, default:False If
Trueandfunccannot be applied to some values, return the dictionary with those values untouched.If
False, raise an error iffunccannot be applied to some values.
- d
- Returns:
dictorNoneEither a new dictionary (if
in_placeisFalse) orNone(ifin_placeisTrue).
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 2} # Define a function to filter out all values strictly # lower than 4 f = lambda x: x > 4 # Filter the dictionary >>> new_d = nestdictutils.map_dict(d, f, in_place = False) >>> new_d {3: {4: 5}, 6: {3: {7: 8}, 7: 10}} # Note that values lower than 4 are still kept as keys, # and only removed if they are values
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: [10]}, 7: 2} # Define a function to filter out all values strictly # lower than 4 f = lambda x: x > 4 # Filter the dictionary >>> new_d = nestdictutils.map_dict(d, f, in_place = False) >>> new_d Traceback (most recent call last): f = lambda x: x > 4 ^^^^^ TypeError: '>' not supported between instances of 'list' and 'int' The above exception was the direct cause of the following exception: Traceback (most recent call last): new_d = nestdictutils.recursive_filter_dict(d, f, in_place = False) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ raise Exception(errstr) from e Exception: Could not apply the function to [10].
- utils.recursive_get_key_paths(d, value)#
Get a list of “key paths” (= sequences of keys) to access a specific value inside the dictionary. If the value is present only once inside the dictionary, the output list will contain only one element.
- Parameters:
- d
dict Input dictionary.
- valueany object apart from
dict Value whose “key paths” will be reported.
- d
- Returns:
listList of “key paths”.
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Get the "key paths" to the value 7 >>> nestdictutils.recursive_get_key_paths(d, 7) [([6, 3], 7), ([6], 7), ([], 7)] # Note that the last "key path" is empty because # 7 is a key of the outer dictionary
- utils.recursive_get_values_from_key(d, key)#
Given a key, returns a list of all values in the dictionary associated with it. Since the dictionary may be nested, the same key could be found at different levels. In this case, the list will contains all values the key has been found associated with.
- Parameters:
- d
dict Input dictionary.
- keyany immutable object
Key of interest.
- d
- Returns:
listList of values associated with the key of interest.
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}}} # Get all values associated with the key 3 >>> nestdictutils.recursive_get_values_from_key(d, 3) [{4: 5}, {7: 8}]
- utils.recursive_get_values_from_keys(d, keys)#
Given a set of keys, returns a list of all values in the dictionary associated with them (since it may be a nested dictionary, the same key could be found at different levels).
- Parameters:
- d
dict Input dictionary.
- keysan iterable of immutable objects
Keys of interest.
- d
- Returns:
dictDictionary of values associated with the corresponding keys of interest.
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}}} # Get all values associated with the keys 3 and 6 >>> nestdictutils.recursive_get_values_from_keys(d, [3, 6]) {3: [{4: 5}, {7: 8}], 6: [{3: {7: 8}}]}
- utils.recursive_iter_key_paths(d)#
Recursively iterate over a dictionary and return a list of tuples containing the “key path” (= sequence of keys) to reach each point in the dictionary and the value that each “key path” leads to.
- Parameters:
- d
dict Input dictionary.
- d
- Returns:
generatorGenerator of “key paths”.
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Get the "key paths" for all items in the dictionary # and list them >>> list(nestdictutils.recursive_iter_key_paths(d)) [([1], 2), ([3, 4], 5), ([3], {4: 5}), ([6, 3, 7], 8), ([6, 3], {7: 8}), ([6, 7], 10), ([6], {3: {7: 8}, 7: 10}), ([7], 11)]
- utils.recursive_map_dict(d, func, keys=None, in_place=False, permissive=False)#
Recursively traverse a dictionary mapping a function to the dictionary’s leaf values (= substituting the values which the return value of the function applied to those values).
- Parameters:
- d
dict The input dictionary.
- funcany callable
Callable taking as inputs the leaf values of the dictionary and returning a value which will take the dictionary’s place.
- keys
list,set, optional List of specific keys on whose items the mapping should be performed. This means that all values associated with keys different from those in the list will not be affected. If
None, all keys and associated values will be considered.- in_place
bool, default:False Whether to modify the input dictionary in place or return a new dictionary.
- permissive
bool, default:False If
Trueandfunccannot be applied to some values, return the dictionary with those values untouched.If
False, raise an error iffunccannot be applied to some values.
- d
- Returns:
dictorNoneEither a new dictionary (if
in_placeisFalse) orNone(ifin_placeisTrue).
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Define a function to raise all values to the power of two f = lambda x: x**2 # Raise all values to the power of two >>> new_d = nestdictutils.map_dict(d, f, in_place = False) >>> new_d
# Create a nested dictionary >>> d = {1: [2], 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Define a function to raise all values to the power of two f = lambda x: x**2 # Raise all values to the power of two >>> new_d = nestdictutils.map_dict(d, f, in_place = False) >>> new_d Traceback (most recent call last): f = lambda x: x**2 ~^^~ TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int' The above exception was the direct cause of the following exception: Traceback (most recent call last): new_d = nestdictutils.map_dict(d, f, in_place = False) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ raise Exception(errstr) from e Exception: Could not apply the function to [2].
- utils.recursive_merge_dicts(dicts)#
Merge two nested dictionaries.
- Parameters:
- dictsiterable of dict
Iterable of dictionaries to be merged.
- Returns:
- ``merged_d``
collections.defaultict Merged dictionary.
- ``merged_d``
Notes
If an identical key at an identical position is found in any two or more input dictionaries, the value in the dictionary that comes first in the iterable will be reported in the merged dictionary.
If the value associated to the key in two or more input dictionaries is a dictionary, the key/value pairs from all these dictionaries will be reported in the merged dictionary.
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Create a second nested dictionary >>> d2 = {14: {15: 16}, 3: 6} # Merge the two dictionaries >>> new_d = nestdictutils.recursive_merge_dicts([d, d2]) >>> new_d {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11, 14: {15: 16}}
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Create a second nested dictionary >>> d2 = {14: {15: 16}, 3: {17: 18}} # Create a third nested dictionary >>> d3 = {6 : {3 : {9:10}}} # Merge the three dictionaries >>> new_d = nestdictutils.recursive_merge_dicts([d, d2, d3]) >>> new_d {1: 2, 3: {4: 5, 17: 18}, 6: {3: {7: 8, 9: 10}, 7: 10}, 7: 11, 14: {15: 16}}
- utils.recursive_pop(d, keys, in_place=False)#
Recursively remove specific keys (and the associated values) from a dictionary.
- Parameters:
- d
dict Input dictionary.
- keysan iterable of immutable objects
The keys to be removed.
- in_place
bool, default:False Whether to modify the input dictionary in place or return a new dictionary.
- d
- Returns:
dictorNoneEither a new dictionary (if
in_placeisFalse) orNone(ifin_placeisTrue).
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Remove keys 3 and 7 and associated values >>> new_d = nestdictutils.recursive_pop(d, (3, 7), False) >>> new_d {1: 2, 6: {}} # Note that all occurrences of the keys have been removed # from the dictionary, not just their outermost instances
- utils.recursive_remove(d, key_path, in_place=False)#
Recursively remove a value in a dictionary given its “key path” (= sequence of keys) in the dictionary.
- Parameters:
- d
dict Input dictionary.
- key_path
tuple The “key path” and the associated value.
- in_place
bool, default:False Whether to modify the input dictionary in place or return a new dictionary.
- d
- Returns:
dictorNoneEither a new dictionary (if
in_placeisFalse) orNone(ifin_placeisTrue).
- Raises:
KeyErrorIf the “key path” is not found in the input dictionary.
ValueErrorIf the “key path” is found in the input dictionary, but it is associated to a value different from the one provided.
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Remove element 11 in the outer dictionary >>> new_d = nestdictutils.recursive_remove(d, ((7,), 11), False) >>> new_d {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}} # Note how also the associated key has been removed from the # dictionary
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Remove element 5 in the inner dictionary {4: 5} >>> new_d = nestdictutils.recursive_remove(d, ((3, 4), 5), False) >>> new_d {1: 2, 3: {}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Note how also the associated key has been removed from the # dictionary
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Try to remove element 5 given a nonexistent path (3, 6) >>> new_d = nestdictutils.recursive_remove(d, ((3, 6), 5), False) KeyError: 'The key path (3, 6) does not exist.'
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Try to remove a nonexistent element 6 from the inner # dictionary {4: 5} >>> new_d = nestdictutils.recursive_remove(d, ((3, 4), 6), False) ValueError: The key path (3, 4) was found, but its associated value in the provided key path (6) does not correspond to the one found in the dictionary (5).
- utils.recursive_replace(d, key_path, in_place=False)#
Recursively replace a value in a dictionary from a “key path” (= sequence of keys) and the associated value.
- Parameters:
- d
dict Input dictionary.
- key_path
tuple The “key path” and the associated value.
- in_place
bool, default:False Whether to modify the input dictionary in place or return a new dictionary.
- d
- Returns:
dictorNoneEither a new dictionary (if
in_placeisFalse) orNone(ifin_placeisTrue).
Examples
# Create a nested dictionary >>> d = {1: 2, 3: {4: 5}, 6: {3: {7: 8}, 7: 10}, 7: 11} # Replace element 5 in the {4: 5} inner dictionary # with 4 >>> new_d = nestdictutils.recursive_replace(d, ((3, 4), 4), False) >>> new_d {1: 2, 3: {4: 4}, 6: {3: {7: 8}, 7: 10}, 7: 11}