Package: draversal
draversalA package for depth-first traversal of Python dictionaries with uniform child fields, supporting both forward and backward navigation.DOCUMENTATION WITH EXAMPLESClass:DictSearchQueryDescriptionProvides utilities for querying nested dictionaries based on various conditions.AttributesOPERATOR_MAP(dict): A mapping of query operators to Python's operator functions.query(dict): The query to execute against the data.support_wildcards(bool): Flag to enable wildcard support in queries.support_regex(bool): Flag to enable regular expression support in queries.BehaviorInitializes with a query and optional flags for supporting wildcards and regular expressions.Provides methods to match keys based on different conditions like wildcards, regular expressions, and exact matches.Executes the query on a nested dictionary and returns the matched fields.Examplequery={'a.b.c':1}dsq=DictSearchQuery(query)data={'a':{'b':{'c':1}},'d':[{'e':2},{'f':3,'g':4}]}result=dsq.execute(data)print(result)# Outputs: {'c': 1}Class:DictTraversalDescriptionDepth-first traverse Python dictionary with a uniform children (and label) field structure.Class initialization takes a dictionary data argument and a mandatory children field which must
correspond to the dictionary children list field. Optionally data can be provided as keyword arguments.Except from child field, all other fields are optional and the rest of the dictionary can be formed freely.Examplechildren_field='sections'data={'title':'root',children_field:[{'title':'Child 1'},{'title':'Child 2',children_field:[{'title':'Grandchild 1'},{'title':'Grandchild 2',children_field:[{'title':'Grandgrandchild'}]}]},{'title':'Child 3'}]}traversal=DictTraversal(data,children_field=children_field)# If you want to validate that data has expected and required fields# with a correct nested structure, you can use validate_data function:try:validate_data(data,children_field,'title')print('Given data is valid.')exceptValueErrorase:print(f'Given data is invalid.{e}')After initialization, a certain methods are available for traversing and modifying the nested tree structure.(# Iter function brings to the root, from which the traversal starts,# but actually the first items has not been reached yetprint(iter(traversal)),# Outputs: {'title': 'root'}# Next function forwards iterator to the first/next item. In this case it is the root.# It yields StopIteration error when the end of the tree has been reached.print(next(traversal)),# Outputs: {'title': 'root'}# Prev function works similar way and it yields StopIteration error,# when the beginning of the tree has been reached.print(prev(next(next(traversal)))),# Outputs: {'title': 'Child 1'}# First function brings to the first item in the list (after root).print(first(traversal)),# Outputs: {'title': 'Child 1'}# Root function brings to the root, from which the traversal starts.# Next item will be first item contra to iter which will give root as# the first item only after calling next.print(root(traversal))# Outputs: {'title': 'root'}# Last function brings to the last item in the list.print(last(traversal)),# Outputs: {'title': 'Child 3'})Root is a special place in a tree. When `DictTraversal` has been initialized, or `iter`/`root` functions are called,
root is a starting point of the tree, which contains the first siblings. To traverse to the first sibling,
either next, first, or move_to_next_item methods must be called.

__Other operations__

```python
# Count the number of all children for the current node
print(traversal.count_children())  # Outputs: 6

# Get the last item in the tree
print(traversal.get_last_item())  # Outputs: {'title': 'Child 3'}

# Search for nodes with a specific title
result = traversal.search('Child 1', label_field='title')
print(result)  # Outputs: [({'title': 'Child 1'}, [0]), ({'title': 'Grandchild 1'}, [1, 0])]

# Add a new child to the current node
traversal.add_child(title='New Child')

# Visualize the tree structure
print(traversal.visualize(label_field='title'))  # Outputs:
# root*
# â”œâ”€â”€ Child 1
# â”œâ”€â”€ Child 2
# â”‚   â”œâ”€â”€ Grandchild 1
# â”‚   â””â”€â”€ Grandchild 2
# â”‚â””â”€â”€ Grandgrandchild
# â”œâ”€â”€ Child 3
# â””â”€â”€ New Child
```

There are a plenty of methods that can be used to further navigate, search, add/modify/remove items and visualize the tree.
This is a short list to them. Please refer to the method docs for further information.

```
demo() -> DictTraversal
first(traversal) -> self
last(traversal) -> self
prev(traversal) -> self/StopIteration
root(traversal) -> self
validate_data(data, children_field, label_field=None) -> None/ValueError
__delitem__(idx) -> self/IndexError/ValueError
__getitem__(idx) -> any/IndexError/ValueError
__init__(*args, children_field=None, **kwargs) -> DictTraversal
__invert__() -> self
__iter__() -> self
__len__() -> int
__neg__() -> self
__next__() -> self/StopIteration
__pos__() -> self
__repr__() -> str
add_child(*idx, **kwargs) -> self
children(sibling_only=False) -> list
count_children(sibling_only=False) -> int
find_paths(label_field, titles) -> list(tuple(dict, list),...)
get_item_by_path(path) -> dict
get_last_item(sibling_only=False) -> dict
get_last_item_and_path(sibling_only=False) -> tuple(dict, list)
get_last_path(sibling_only=False) -> list
get_next_item_and_path(sibling_only=False) -> tuple(dict, list)
get_parent_item() -> dict
get_parent_item_and_path(with_children=False) -> tuple(dict, list)
get_parent_path() -> list
get_previous_item_and_path(sibling_only=False) -> tuple(dict, list)
insert_child(idx, **kwargs) -> self
@contextmanager inverted() -> DictTraversal
max_depth() -> int
modify(key=None, value=None, **kwargs) -> self
move_to_next_item(sibling_only=False) -> self
move_to_prev_item(sibling_only=False) -> self
@contextmanager new_root(merge=False) -> DictTraversal
peek_next(steps=1) -> dict
peek_prev(steps=1) -> dict
pretty_print(label_field=None) -> None
replace_child(idx, **kwargs) -> self
search(query, label_field=None) -> list(tuple(dict, list),...)
set_last_item_as_current(sibling_only=False) -> self
set_parent_item_as_current() -> self
set_path_as_current(path) -> self
visualize(label_field=None, from_root=False) -> str
```Method:demoDescriptionInitializes and returns aDictTraversalobject with sample data.BehaviorCreates a nested dictionary structure withtitleandsectionsfields.Initializes aDictTraversalobject with the sample data.Exampletraversal=demo()traversal.pretty_print()# Outputs:# root#   Child 1#   Child 2#     Grandchild 1#     Grandchild 2#       Grandgrandchild#   Child 3Method:firstDescriptionMoves the traversal to the first item relative to the root.Parameterstraversal(DictTraversal): TheDictTraversalobject to operate on.BehaviorMoves the traversal to the first item in the tree, updating thecurrentattribute.Examplefirst(traversal)# Returns: {'title': 'Child 1'}Method:flatten_dictDescriptionFlattens a nested dictionary into a single-level dictionary.Parametersdata(dict): The nested dictionary to flatten.field_separator(str, optional): The separator for nested keys. Defaults to '.'.list_index_indicator(str, optional): The format string for list indices. Defaults to '#%s'.BehaviorRecursively traverses the nested dictionary and flattens it.Handles nested dictionaries and lists of dictionaries.Examplenested_dict={'a':{'b':{'c':1}},'d':[{'e':2},{'f':3,'g':4}]}flat_dict=flatten_dict(nested_dict)print(flat_dict)# Outputs: {'a.b.c': 1, 'd#0.e': 2, 'd#1.f': 3, 'd#1.g': 4}flat_dict=flatten_dict(nested_dict,list_index_indicator='[%s]')print(flat_dict)# Outputs: {'a.b.c': 1, 'd[0].e': 2, 'd[1].f': 3, 'd[1].g': 4}Method:lastDescriptionMoves the traversal to the last item from the current item perspective.Parameterstraversal(DictTraversal): TheDictTraversalobject to operate on.BehaviorMoves the traversal to the last item in the tree, updating thecurrentattribute.Examplelast(traversal)# Returns: {'title': 'Child 3'}# Calling the end item, same will be returnedlast(traversal)# Returns: {'title': 'Child 3'}Method:prevDescriptionMoves the traversal to the previous item relative to the current item.Parameterstraversal(DictTraversal): TheDictTraversalobject to operate on.RaisesStopIteration: If there are no more items to traverse in the backward direction.BehaviorUpdates thecurrentattribute to point to the previous item in the tree.Influenced by theinvertedcontext manager.NoteServes as a counterpart to Python's built-innextfunction.Does not support asiblings_onlyargument; usemove_to_next_itemormove_to_prev_itemdirectly for that.Unlikemove_to_next_itemandmove_to_prev_item, which cycle through the tree,prevraises StopIteration when reaching the end.Example# With default contextlast(traversal)try:print(traversal['title'])# Output: Grandgrandchildprev(traversal)print(traversal['title'])# Output: Grandchild 2exceptStopIteration:print('No more items to traverse.')# With inverted contextlast(traversal)withtraversal.inverted():try:print(traversal['title'])# Output: Grandgrandchildprev(traversal)print(traversal['title'])# Output: Child 3exceptStopIteration:print('No more items to traverse.')Method:reconstruct_itemDescriptionReconstructs an item from a nested dictionary based on a flattened query key.Parametersquery_key(str): The query key to use for reconstruction.item(dict): The nested dictionary.field_separator(str, optional): The separator for nested keys. Defaults to '.'.list_index_indicator(str, optional): The indicator for list indices. Defaults to '#%s'.BehaviorSplits the query key usingfield_separatorandlist_index_indicator.Traverses the flattened dictionary to reconstruct the original nested structure.If the query key ends with a list index indicator (e.g., '#0'), the function returns the item at that index in the list.If the query key ends with a regular key, the function returns a dictionary containing that key and its corresponding value.List Index Indicator:Thelist_index_indicatoris used to specify indices in lists within the nested dictionary.The default indicator is '#%s', where '%s' is a placeholder for the index number.The indicator can be customized. For example, using '[%s]' would allow list indices to be specified like 'd[0].e'.Exampledata={'a':{'b':{'c':1}},'d':[{'e':2},{'f':3,'g':4}]}print(reconstruct_item('a.b.c',data))# Outputs: {'c': 1}print(reconstruct_item('a.b',data))# Outputs: {'b': {'c': 1}}print(reconstruct_item('a',data))# Outputs: {'a': {'b': {'c': 1}}}print(reconstruct_item('d#0.e',data))# Outputs: {'e': 2}print(reconstruct_item('d#1',data))# Outputs: {'f': 3, 'g': 4}print(reconstruct_item('d[0].e',data,list_index_indicator='[%s]'))# Outputs: {'e': 2}print(reconstruct_item('d[1]',data,list_index_indicator='[%s]'))# Outputs: {'f': 3, 'g': 4}Method:rootDescriptionResets the traversal to the root item.Parameterstraversal(DictTraversal): TheDictTraversalobject to operate on.BehaviorResets the traversal to the root item, updating thecurrentattribute.Exampleroot(traversal)# Returns: {'title': 'root'}Method:translateDescriptionTranslate a shell PATTERN to a regular expression.There is no way to quote meta-characters.Method:validate_dataDescriptionValidates a nested dictionary structure for specific field requirements.Parametersdata(dict): The nested dictionary to validate.children_field(str): The field name that contains child dictionaries.label_field(str, optional): The field name that should exist in each dictionary, including the root.RaisesValueError: If any of the validation conditions are not met.BehaviorValidates that the root is a non-empty dictionary.Validates that thechildren_fieldexists in the root iflabel_fieldis not provided.Validates thatlabel_fieldexists in each nested dictionary, if specified.Validates that eachchildren_fieldis a list.Validates that each child inchildren_fieldis a non-empty dictionary.Exampletry:validate_data({'title':'root','sections':[{'title':'Child'}]},'sections','title')print('Given data is valid.')exceptValueErrorase:print(f'Given data is invalid.{e}')Method:DictTraversal.__delitem__DescriptionDeletes an item based on the given index.Parametersidx(int, slice, tuple, list, str): The index to delete the item.Attributescurrent(dict): The current item in the traversal, updated after deletion.RaisesIndexError: If children are not found at the given index.ValueError: If index type is not supported.BehaviorIf index is an int or slice, deletes child items from the current item.If index is a tuple or list, traverses the nested children to delete the item.If index is a string, deletes the corresponding attribute in the current item.Exampledelobj[0]# Deletes the first child of the current itemdeltraversal[(0,0)]# Deleted the first child of the first child of the current itemdeltraversal[1:2]# Deleted the second and third children of the current itemdelobj['name']# Deletes the name attribute of the current itemMethod:DictTraversal.__getitem__DescriptionRetrieves an item based on the given index.Parametersidx(int, slice, tuple, list, str): The index to retrieve the item.Attributescurrent(dict): The current item in the traversal.children_field(str): The key used to identify children in the dictionary.RaisesIndexError: If children are not found at the given index.ValueError: If index type is not supported.BehaviorIf index is an int or slice, retrieves child items from the current item.If index is a tuple or list, traverses the nested children to retrieve the item.If index is a string, retrieves the value of the corresponding attribute in the current item.Exampleitem=traversal[0]# Retrieves the first child of the current itemitem=traversal[(0,0)]# Retrieves the first child of the first child of the current itemitems=traversal[1:2]# Retrieves the second and third children of the current itemitem=traversal['name']# Retrieves the name attribute of the current itemMethod:DictTraversal.__init__DescriptionInitializes theDictTraversalobject.Parameters*args(list): Variable-length argument list to initialize the dictionary.children_field(str): The key used to identify children in the dictionary.**kwargs(dict): Arbitrary keyword arguments to initialize the dictionary.Attributeschildren_field(str): The key used to identify children in the dictionary.path(list): Keeps track of the traversal path.current(dict): Points to the current item in the traversal.iter_method(func): Function used for moving to the next/previous item during iteration.next_iteration_start(bool): Flag used to control the behavior of__iter__()/__next__().prev_iteration_stop(bool): Flag used to control the behavior of__iter__()/prev().inverted_context(bool): Flag to indicate whether the iteration context ie. direction manipulated bywithis inverted or not.RaisesValueError: Ifchildren_fieldis not provided or is not a string.BehaviorInitializes the underlying dictionary with the given*argsand**kwargs.Sets thechildren_fieldattribute for identifying child items in the dictionary.Initializespathas an empty list to keep track of the traversal path.Setscurrentto point to the root item (self).Setsiter_methodto usemove_to_next_itemby default for iteration.Initializesinverted_contextas False.NoteKeyword arguments will override arguments in*argsif overlapping keys are found.Exampletraversal=DictTraversal(data,children_field='children')Method:DictTraversal.__iter__DescriptionInitializes the iterator for theDictTraversalobject.Attributespath(list): Reset to an empty list.current(dict): Reset to point to the root item.BehaviorInitializes the iterator for theDictTraversalobject.Resets the traversal to the root item.Returns theDictTraversalobject itself to make it an iterator.NoteThis method resets the traversal to the root item.Example# Using __iter__ to reset traversal to root, but next-function is actually required to move to the root!iter(traversal)# Represents: {'title': 'root'}Method:DictTraversal.__neg__DescriptionMoves the traversal to the previous item.BehaviorCan be invoked using the-unary operator.Updates thepathandcurrentattributes to reflect the new traversal path.Exampleprint(last(traversal)['title'])# Outputs: 'Child 3'print((-traversal)['title'])# Outputs: 'Grandgrandchild'Method:DictTraversal.__next__DescriptionAdvances the iterator to the next item in the traversal.Attributespath(list): Updated to reflect the new traversal path.current(dict): Updated to point to the next item in the traversal.RaisesStopIteration: If there are no more items to traverse.BehaviorAdvances the iterator to the next item in the traversal.Updates the path and current attributes to reflect the new traversal path.NoteThis method moves the traversal to the next item relative to the current item.Unlikemove_to_next_itemandmove_to_prev_item, which jump over the root and continue from start/end,prevwill raise a StopIteration error when it reaches the end of the traversal.Example# Using __next__ to move to the next itemtry:iter(traversal)next(traversal)# Represents: {'title': 'root'}next(traversal)# Represents: {'title': 'Child 1'}exceptStopIteration:print('No more items to traverse.')Method:DictTraversal.__pos__DescriptionMoves the traversal to the next item.BehaviorCan be invoked using the+unary operator.Updates thepathandcurrentattributes to reflect the new traversal path.Exampleprint(root(traversal)['title'])# Outputs: 'root'print((+traversal)['title'])# Outputs: 'Child 1'Method:DictTraversal.add_childDescriptionAdds a new child item to the current item's children.Parameters*idx: Integer arguments to define the path to the subitems/children, in which to add the item.**kwargs: Arbitrary keyword arguments to define the new child item.Attributescurrent(dict): The current item in the traversal, updated with the new child.BehaviorAdds a new child item with the given keyword arguments to the current item's children list.Initializes the children list if it doesn't exist.Exampletraversal.add_child(title='Child X')print(last(traversal))# Outputs: {'title': 'Child X'}Method:DictTraversal.childrenDescriptionRetrieves the children of the current item.Parameterssibling_only(bool, optional): If True, returns only the siblings of the current item.BehaviorIf sibling_only is True, returns a list of siblings without their children.Otherwise, returns a list of children including their own children.Examplenext(next(root(traversal)))# Move to Child 2print(traversal.children())# Output: [{'title': 'Grandchild 1'}, {'title': 'Grandchild 2', 'sections': [{'title': 'Grandgrandchild'}]}]print(traversal.children(sibling_only=True))# Output: [{'title': 'Grandchild 1'}, {'title': 'Grandchild 2'}]Method:DictTraversal.count_childrenDescriptionCounts the number of child items in the current traversal context.Parameterssibling_only(bool): Whether to count only immediate children. Default is False.Attributescurrent(dict): The current item in the traversal.children_field(str): The key used to identify children in the dictionary.BehaviorIfsibling_onlyis True, counts only the immediate children of the current item.Ifsibling_onlyis False, counts all descendants of the current item recursively.Utilizes a private recursive function_for counting whensibling_onlyis False.Notetraversal.count_children()is same aslen(traversal)traversal.count_children(sibling_only=True)is same aslen(traversal[:])Examplecount=traversal.count_children(sibling_only=True)# Counts only immediate childrenprint(count)# Outputs: 3count=traversal.count_children()# Counts all descendantsprint(count)# Outputs: 6Method:DictTraversal.find_pathsDescriptionLocate items by matching their titles to a list of specified field values.Parameterslabel_field(str): Field name to be used as label of each item. Default is None.titles(list or str): Field values to match against item titles. Can be a single string or a list of strings.BehaviorConvertstitlesto a list if it's a single string.Initializes an empty listresultsto store matching items and their paths.Defines a recursive function_to search for items with matching titles.Calls_starting from the current item's subitems, passing the list of remaining titles to match.Appends matching items and their paths toresults. Items in the result list do not contain childrens.Exampletraversal.find_paths('title',['Child 2','Grandchild 1'])# Returns: [({'title': 'Grandchild 1'}, [1, 0])Method:DictTraversal.getDescriptionRetrieves the value at the specified index key at the current item.Parametersidx(int, slice, tuple, list, str): The index key to retrieve the value from.default(any, optional): The default value to return if the index key is not found.BehaviorRetrieves the value at the given index key from the object.If the index key is not found or the value is None, returns the default value.Examplevalue=traversal.get('new_field',default='Not Found')print(value)# Output will be the value of the key 'new_field' or 'Not Found'Method:DictTraversal.get_item_by_pathDescriptionRetrieves the item located at the specified path in the traversal.Parameterspath(list): The path to the item in the traversal, represented as a list of integers.NoteThe method uses the traversal's__getitem__method to fetch the item.ReturnsNoneif the path does not exist.Exampletraversal.get_item_by_path([1,0])# Returns: {'title': 'Grandchild 1'}Method:DictTraversal.get_last_itemDescriptionRetrieves the last item in the current traversal tree from the current item perspective.Parameterssibling_only(bool, optional): If True, considers only the siblings.Example# Under rootprint(traversal.get_last_item())# Output: {'title': 'Child 3'}# Under Child 2next(next(traversal))print(traversal.get_last_item())# Output: {'title': 'Grandgrandchild'}Method:DictTraversal.get_last_item_and_pathDescriptionRetrieves the last item and its path in the traversal tree from the current item perspective.Parameterssibling_only(bool, optional): If True, considers only the siblings.BehaviorIf sibling_only is True, returns the last sibling and its path.Otherwise, returns the last item in the deepest nested list and its path.Exampleitem,path=traversal.get_last_item_and_path()print(item)# Output: {'title': 'Child 3'}print(path)# Output: [2]Method:DictTraversal.get_last_pathDescriptionRetrieves the path to the last item in the traversal from the current item perspective.Parameterssibling_only(bool, optional): If True, considers only the siblings.Example# Under rootprint(traversal.get_last_path())# Output: [2]# Under Child 2next(next(traversal))print(traversal.get_last_path())# Output: [1, 1, 0]Method:DictTraversal.get_next_item_and_pathDescriptionRetrieves the next item and its path without altering the state of the object.Parameterssibling_only(bool, optional): If True, considers only the siblings.BehaviorRetrieves the next item and its path relative to the current item.If sibling_only is True, returns the next sibling and its path.Exampleroot(traversal)item,path=traversal.get_next_item_and_path()print(item)# Output: {'title': 'Child 1'}print(path)# Output: [0]Method:DictTraversal.get_parent_itemDescriptionRetrieves the parent item of the current item in the traversal.BehaviorReturns the parent item without its children.Returns None if the current item is the root.Exampleroot(traversal)# Move to Grandchild 1(+++traversal).get_parent_item()# Returns: {'title': 'Child 2'}Method:DictTraversal.get_parent_item_and_pathDescriptionRetrieves both the parent item and the path to the parent of the current item in the traversal.Parameterswith_children(bool, optional): If True, return the whole traversal tree, not only siblings without children.NoteReturns(None, [])if the current item is the root.Beware to setself.currentto None since it is expected always to be a dictionary - either a root or subitem.Exampleroot(traversal)(+++traversal).get_parent_item_and_path()# Returns: ({'title': 'Child 2'}, [1])Method:DictTraversal.get_parent_pathDescriptionRetrieves the path to the parent of the current item in the traversal.BehaviorReturns an empty list if the current item is the root.Exampleroot(traversal)# Move to Grandchild 1(+++traversal).get_parent_path()# Returns: [1]---# Method: `DictTraversal.get_previous_item_and_path`## DescriptionRetrievesthepreviousitemanditspathwithoutalteringthestateoftheobject.## Parameters-__sibling_only__(bool,optional):IfTrue,considersonlythesiblings.## Behavior-Retrievesthepreviousitemanditspathrelativetothecurrentitem.-Ifsibling_onlyisTrue,returnstheprevioussiblinganditspath.## Example```pythonroot(traversal)item,path=traversal.get_previous_item_and_path()print(item)# Output: {'title': 'Child 3'}print(path)# Output: [2]Method:DictTraversal.insert_childDescriptionInserts a new child item at a specific index in the current item's children.Parametersidx(int, list, tuple): The index at which to insert the new child. Can be a list or tuple of indices, which points to the deeper hierarchy of children.**kwargs: Arbitrary keyword arguments to define the new child item.Attributescurrent(dict): The current item in the traversal, updated with the new child.BehaviorInserts a new child item with the given keyword arguments at the specified index.Initializes the children list if it doesn't exist.Exampletraversal.insert_child(0,title='Child X')print(first(traversal))# Outputs: {'title': 'Child X'}Method:DictTraversal.invertedDescriptionContext manager for backward traversal.BehaviorTemporarily setsiter_methodtomove_to_prev_item.Restores the originaliter_methodafter exiting the context.Affects the behavior of the following methods:next, prevpeek_next, peek_prevfor loop iterationfirst, lastroot, move_to_next_item, and move_to_prev_item are NOT affectedNoteThis context manager can be nested.The state ofinverted_contextwill be restored after exiting each with-block.Example# Forward traversal (default behavior)foritemintraversal:print(item)# Backward traversal using the inverted context managerwithtraversal.inverted():foritemintraversal:print(item)Method:DictTraversal.max_depthDescriptionReturns the maximum depth of the traversal tree of the current item.BehaviorCalculates the maximum depth of the traversal tree.Depth starts from 0 at the root.Exampleprint(traversal.max_depth())# Output: 3Method:DictTraversal.modifyDescriptionModifies the current item's attributes.Parameterskey(str, optional): The key of the attribute to modify.value: The new value for the specified key.**kwargs: Arbitrary keyword arguments to update multiple attributes.Attributescurrent(dict): The current item in the traversal, updated with the new attributes.BehaviorUpdates the current item's attributes based on the provided key-value pairs.Ifkeyandvalueare provided, updates that specific attribute.Ifkwargsare provided, updates multiple attributes.Exampletraversal.modify(title='ROOT')print(traversal)# Outputs: {'title': 'ROOT'}Method:DictTraversal.move_to_next_itemDescriptionMoves the traversal to the next item.Parameterssibling_only(bool, optional): If True, moves only among siblings.Attributescurrent(dict): Updated to point to the next item in the traversal.path(list): Updated to reflect the new traversal path.BehaviorMoves the traversal to the next item relative to the current item.If sibling_only is True, moves only among siblings.Will start over beginning after reaching the end.Exampleroot(traversal)traversal.move_to_next_item()print(traversal)# Output: {'title': 'Child 1'}Method:DictTraversal.move_to_prev_itemDescriptionRetrieves the previous item and its path without altering the state of the object.Parameterssibling_only(bool, optional): If True, considers only the siblings.BehaviorRetrieves the previous item and its path relative to the current item.If sibling_only is True, returns the previous sibling and its path.Will start over the the end after reaching the beginning.Exampleroot(traversal)traversal.move_to_prev_item()print(traversal)# Output: {'title': 'Child 3'}Method:DictTraversal.new_rootDescriptionContext manager for temporarily setting a new root for traversal.Parametersmerge(bool): Whether to merge the changes back to the original object. Default is False.Attributescurrent(dict): Points to the new root item in the traversal ifmergeis True.path(list): Restored to its original state ifmergeis True.inverted_context(bool): Inherits the value from the original object.BehaviorIfmergeis True, creates a newDictTraversalobject with the current item as root.Ifmergeis False, creates a deep copy of the currentDictTraversalobject.Yields the newDictTraversalobject for use within the context.Ifmergeis True, updates the root fields and restores the original path after exiting the context.Examplewithtraversal.new_root(merge=True)asnew_obj:# Perform operations on new_obj from the relative traversal path perspective# Modifications will affect to the original traversal traversal after with blockwithtraversal.new_root(merge=False)asnew_obj:# Perform operations on new_obj from the relative traversal path perspective# Modifications will not affect to the original traversal object after with blockMethod:DictTraversal.peek_nextDescriptionPeeks at the next item(s) in the traversal without altering the current pointer.Parameterssteps(int, optional): Number of steps to peek ahead. Defaults to 1.BehaviorCycles back to the root if the end is reached.Temporarily alters the current item and path, restoring them before returning.Notestepsmust be a positive integer.Influenced by theinvertedcontext manager.Exampleprint(traversal.peek_next(2))# Output: {'title': 'Child 2'}# With inverted contextwithtraversal.inverted():print(traversal.peek_next(2))# Output: {'title': 'Grandgrandchild'}Method:DictTraversal.peek_prevDescriptionPeeks at the previous item(s) in the traversal without altering the current pointer.Parameterssteps(int, optional): Number of steps to peek back. Defaults to 1.BehaviorCycles back to the end if the start is reached.Temporarily alters the current item and path, restoring them before returning.Notestepsmust be a positive integer.Influenced by theinvertedcontext manager.Exampleprint(traversal.peek_prev(2))# Output: {'title': 'Grandgrandchild'}# With inverted contextwithtraversal.inverted():traversal.peek_prev(2)# Output: {'title': 'Child 2'}Method:DictTraversal.pretty_printDescriptionRecursively print the tree from the relative current item in a formatted manner.Parameterslabel_field(str): Field name to be used as label of each item. Default is None.BehaviorPrints the string representation of the traversal tree, indented by the specified amount.If label_field is not given, repr is used to show the item excluding its children.Recursively traverses (inner function_) and prints all children,
incrementing the indentation level by 1 for each level.Exampletraversal.pretty_print(label_field='title')# Output:# root#   Child 1#   Child 2#      Grandchild 1#      Grandchild 2#          Grandchildchild#   Child 3Method:DictTraversal.replace_childDescriptionReplaces an existing child item at a specific index in the current item's children.Parametersidx(int, list, tuple): The index of the child to replace. Can be a list or tuple of indices, which points to the deeper hierarchy of children.**kwargs: Arbitrary keyword arguments to define the new child item.Attributescurrent(dict): The current item in the traversal, updated with the new child.BehaviorReplaces the child item at the specified index with a new item defined by the keyword arguments.Initializes the children list if it doesn't exist.Exampletraversal.replace_child(0,title='CHILD 1')print(first(traversal))# Outputs: {'title': 'CHILD 1'}Method:DictTraversal.searchDescriptionSearch for items whose label match a given query.Parametersquery(str, DictSearchQuery or re.Pattern): The search query, either a string, DictSearchQuery or a regular expression pattern.label_field(str): Field name to be used as a target of search for each item, if query isstrorre.Pattern. Default is None.BehaviorInitializes an empty listresultsto store matching items and their paths.Defines a nested function_to recursively search for items with matching titles.Calls_starting from the current item's subitems.Appends matching items and their paths toresults.Returnsresults.Exampleresult1=traversal.search('Grandgrandchild','title')# Returns: [({'title': 'Grandgrandchild'}, [1, 1, 0])]result2=traversal.search(re.compile(r'Grandchild [0-9]+'),'title')# Returns: [({'title': 'Grandchild 1'}, [1, 0]), ({'title': 'Grandchild 2'}, [1, 1])]Method:DictTraversal.set_last_item_as_currentDescriptionSets the last item in the traversal as the current item from the current item perspective.Parameterssibling_only(bool, optional): If True, considers only the siblings.Attributescurrent(dict): Updated to point to the last item in the traversal.path(list): Updated to reflect the new traversal path.Exampletraversal.set_last_item_as_current()print(traversal)# Output: {'title': 'Child 3'}Method:DictTraversal.set_parent_item_as_currentDescriptionSets the parent item in the traversal as the current item from the current item perspective.Attributescurrent(dict): Updated to point to the parent item in the traversal.path(list): Updated to reflect the new traversal path.Example+++traversal# Grandchild 1traversal.set_parent_item_as_current()print(traversal)# Output: {'title': 'Child 2'}Method:DictTraversal.set_path_as_currentDescriptionSets the item located at the specified path as the current item in the traversal.Parameterspath(list): The path to the item in the traversal, represented as a list of integers.NoteUpdates bothself.currentandself.pathattributes.If the item does not exist at the specified path,self.currentandself.pathare not updated.Exampletraversal.set_path_as_current([1,0])# Sets the current item to the one located at path [1, 0]Method:DictTraversal.visualizeDescriptionGenerates a string representation of the traversal tree.Parameterslabel_field(str, optional): Field name to be used as the label for each item. Default is None.from_root(bool): Whether to start the visualization from the root item. Default is False.Attributescurrent(dict): The current item in the traversal.children_field(str): The key used to identify children in the dictionary.BehaviorIffrom_rootis True, starts the visualization from the root item.Iflabel_fieldis provided, uses it as the label for each item.Marks the current item with an asterisk (*).Exampleprint(next(root(traversal)).visualize('title',from_root=True))# Output:# root# â”œâ”€â”€ Child 1*# â”œâ”€â”€ Child 2# â”‚   â”œâ”€â”€ Grandchild 1# â”‚   â””â”€â”€ Grandchild 2# â”‚       â””â”€â”€ Grandgrandchild# â””â”€â”€ Child 3print(next(next(root(traversal))).visualize('title'))# Output:# Child 2*# â”œâ”€â”€ Grandchild 1# â””â”€â”€ Grandchild 2#     â””â”€â”€ GrandgrandchildMethod:DictSearchQuery.__init__DescriptionInitializes a DictSearchQuery object.Parametersquery(dict): The query to execute.support_wildcards(bool, optional): Flag to enable wildcard support. Defaults to True.support_regex(bool, optional): Flag to enable regex support. Defaults to True.field_separator(str, optional): The separator for nested keys. Defaults to '.'.list_index_indicator(str, optional): The indicator for list indices. Defaults to '#%s'.operator_separator(str, optional): The separator between field and operator. Defaults to '$'.BehaviorInitializes the query, and sets flags for wildcard and regex support.Examplequery={'a.b.c':1}dsq=DictSearchQuery(query)data={'a':{'b':{'c':1}},'d':[{'e':2},{'f':3,'g':4}]}result=dsq.execute(data)print(result)# Outputs: {'c': 1}Method:DictSearchQuery.executeDescriptionExecutes the query on the data.Parametersdata(dict): The data to query.field_separator(str, optional): The separator for nested keys. Defaults toself.field_separator = '.'.list_index_indicator(str, optional): The format string for list indices. Defaults toself.list_index_indicator = '#%s'.BehaviorFlattens the data usingflatten_dict.Matches fields based on the query and returns them.Examplequery={'*':1}dsq=DictSearchQuery(query)data={'a':{'b':{'c':1}},'d':[{'e':2},{'f':3,'g':4}]}dsq.execute(data)# Results: {'c': 1}Method:DictSearchQuery.reconstruct_itemDescriptionReconstructs an item from a nested dictionary based on a flattened query key, using the instance's field separator and list index indicator.Parametersquery_key(str): The query key to use for reconstruction.item(dict): The nested dictionary.NoteUtilizes the standalonereconstruct_itemfunction.Usesself.field_separatorandself.list_index_indicatorfor the reconstruction.Exampledata={'a':{'b':{'c':1}},'d':[{'e':2},{'f':3,'g':4}]}DictSearchQuery().reconstruct_item('a.b.c',data)# Returns: {'c': 1}