Skip to content

📝 Modify

There are two types of modification available

  1. Non-replacing scenario: Shift or copy nodes within same tree or between two trees using from_paths (list of paths) and to_paths (list of paths).
  2. Replacing scenario: Shift or copy nodes within same tree or between two trees while replacing the to-node using from_paths (list of paths) and to_paths (list of paths).

Available Configurations for Customization

In non-replacing scenario, there are several configurations available for customization.

Configuration Description Default Value
copy Indicates whether it is to shift the nodes, or copy the nodes False (nodes are shifted, not copied)
to_tree Indicates whether shifting/copying is within the same tree, or between different trees None (nodes are shifted/copied within the same tree)
skippable Skip shifting/copying of nodes if from_path cannot be found False (from-node must be found)
overriding Override existing node if it exists False (to-node must not exist)
merge_children Shift/copy children of from-node and remove intermediate parent node False (children are not merged)
merge_leaves Shift/copy leaves of from-node and remove all intermediate nodes False (leaves are not merged)
delete_children Shift/copy node only and delete its children False (nodes are shifted/copied together with children)

In replacing scenario, all the configurations are also available except overriding, merge_children, and merge_leaves as it is doing a one-to-one replacement. It is by default overriding, and there is nothing to merge.

Note

merge_children and merge_leaves cannot be simultaneously set to True.

Note

Error will always be thrown if multiple from-nodes are found, paths in from_paths must be unique.

Tree Modification Permutations

There are several ways you can mix and match the tree modification methods. If you know all the parameters to choose, feel free to use copy_or_shift_logic or replace_logic methods as they are the most customizable. All other methods calls these 2 methods directly.

Shift / Copy? Same tree / Between two trees? Replace destination node? Method to use
Shift Same tree No shift_nodes
Copy Same tree No copy_nodes
Copy Between two trees No copy_nodes_from_tree_to_tree
Any Any No copy_or_shift_logic
Shift Same tree Yes shift_and_replace_nodes
Copy Between two trees Yes copy_and_replace_nodes_from_tree_to_tree
Any Any Yes replace_logic

Tree Modification Illustration

Shift and Copy Example

Sample Tree Modification (Shift, Copy, Delete)

Setting Sample path in from_paths Sample path in to_paths Description
Default "/a/c" "/a/b/c" Shift/copy node c
Default "/c" "/a/b/c" Shift/copy node c
Default "c" "/a/b/c" Shift/copy node c
Default "/a/e" None Delete node e
skippable "/a/c" "/a/b/c" Shift/copy node c, skip if "/a/c" cannot be found

Advanced Shift Example

Sample Tree Modification (Advanced)

Setting Sample path in from_paths Sample path in to_paths Description
overriding "a/b/c" "a/d/c" Shift/copy node c, override if "a/d/c" exists
merge_children "a/b/c" "a/d/c" If path not present: Shift/copy children of node c to be children of node d, removing node c
If path present: Shift/copy children of node c to be merged with existing "a/d/c" children
merge_children + overriding "a/b/c" "a/d/c" If path not present: Behaves like merge_children
If path present: Behaves like overriding
merge_leaves "a/b/c" "a/d/c" If path not present: Shift/copy leaves of node c to be children of node d
If path present: Shift/copy leaves of node c to be merged with existing "a/d/c" children
- merge_leaves + overriding "a/b/c" "a/d/c" If path not present: Behaves like merge_leaves
If path present: Behaves like overriding, but original node c remains
delete_children "a/b" "a/d/b" Shift/copy node b only without any node b children

bigtree.tree.modify

shift_nodes

shift_nodes(
    tree,
    from_paths,
    to_paths,
    sep="/",
    skippable=False,
    overriding=False,
    merge_children=False,
    merge_leaves=False,
    delete_children=False,
    with_full_path=False,
)

Shift nodes from from_paths to to_paths in-place.

  • Creates intermediate nodes if to path is not present
  • Able to skip nodes if from path is not found, defaults to False (from-nodes must be found; not skippable).
  • Able to override existing node if it exists, defaults to False (to-nodes must not exist; not overridden).
  • Able to merge children and remove intermediate parent node, defaults to False (nodes are shifted; not merged).
  • Able to merge only leaf nodes and remove all intermediate nodes, defaults to False (nodes are shifted; not merged)
  • Able to shift node only and delete children, defaults to False (nodes are shifted together with children).

For paths in from_paths and to_paths,

  • Path name can be with or without leading tree path separator symbol.

For paths in from_paths,

  • Path name can be partial path (trailing part of path) or node name.
  • If with_full_path=True, path name must be full path.
  • Path name must be unique to one node.

For paths in to_paths,

  • Path name must be full path.
  • Can set to empty string or None to delete the path in from_paths, note that copy must be set to False.

If merge_children=True,

  • If to_path is not present, it shifts children of from_path.
  • If to_path is present, and overriding=False, original and new children are merged.
  • If to_path is present and overriding=True, it behaves like overriding and only new children are retained.

If merge_leaves=True,

  • If to_path is not present, it shifts leaves of from_path.
  • If to_path is present, and overriding=False, original children and leaves are merged.
  • If to_path is present and overriding=True, it behaves like overriding and only new leaves are retained, original non-leaf nodes in from_path are retained.

Examples:

>>> from bigtree import list_to_tree, str_to_tree, shift_nodes
>>> root = list_to_tree(["Downloads/photo1.jpg", "Downloads/file1.doc"])
>>> root.show()
Downloads
├── photo1.jpg
└── file1.doc
>>> shift_nodes(
...     tree=root,
...     from_paths=["Downloads/photo1.jpg", "Downloads/file1.doc"],
...     to_paths=["Downloads/Pictures/photo1.jpg", "Downloads/Files/file1.doc"],
... )
>>> root.show()
Downloads
├── Pictures
│   └── photo1.jpg
└── Files
    └── file1.doc

To delete node,

>>> root = list_to_tree(["Downloads/photo1.jpg", "Downloads/file1.doc"])
>>> root.show()
Downloads
├── photo1.jpg
└── file1.doc
>>> shift_nodes(root, ["Downloads/photo1.jpg"], [None])
>>> root.show()
Downloads
└── file1.doc

In overriding case,

>>> root = str_to_tree(
... "Downloads\n"
... "├── Misc\n"
... "│   └── Pictures\n"
... "│       └── photo1.jpg\n"
... "└── Pictures\n"
... "    └── photo2.jpg"
... )
>>> root.show()
Downloads
├── Misc
│   └── Pictures
│       └── photo1.jpg
└── Pictures
    └── photo2.jpg
>>> shift_nodes(root, ["Downloads/Misc/Pictures"], ["Downloads/Pictures"], overriding=True)
>>> root.show()
Downloads
├── Misc
└── Pictures
    └── photo1.jpg

In merge_children=True case, child nodes are shifted instead of the parent node.

  • If the path already exists, child nodes are merged with existing children.
  • If same node is shifted, the child nodes of the node are merged with the node's parent.
>>> root = str_to_tree(
... "Downloads\n"
... "├── Misc\n"
... "│   ├── Pictures\n"
... "│   │   └── photo2.jpg\n"
... "│   └── Applications\n"
... "│       └── Chrome.exe\n"
... "├── Pictures\n"
... "│   └── photo1.jpg\n"
... "└── dummy\n"
... "    └── Files\n"
... "        └── file1.doc"
... )
>>> root.show()
Downloads
├── Misc
│   ├── Pictures
│   │   └── photo2.jpg
│   └── Applications
│       └── Chrome.exe
├── Pictures
│   └── photo1.jpg
└── dummy
    └── Files
        └── file1.doc
>>> shift_nodes(
...     root,
...     ["Downloads/Misc/Pictures", "Applications", "Downloads/dummy"],
...     ["Downloads/Pictures", "Downloads/Applications", "Downloads/dummy"],
...     merge_children=True,
... )
>>> root.show()
Downloads
├── Misc
├── Pictures
│   ├── photo1.jpg
│   └── photo2.jpg
├── Chrome.exe
└── Files
    └── file1.doc

In merge_leaves=True case, leaf nodes are copied instead of the parent node.

  • If the path already exists, leaf nodes are merged with existing children.
  • If same node is copied, the leaf nodes of the node are merged with the node's parent.
>>> root = str_to_tree(
... "Downloads\n"
... "├── Misc\n"
... "│   ├── Pictures\n"
... "│   │   └── photo2.jpg\n"
... "│   └── Applications\n"
... "│       └── Chrome.exe\n"
... "├── Pictures\n"
... "│   └── photo1.jpg\n"
... "└── dummy\n"
... "    └── Files\n"
... "        └── file1.doc"
... )
>>> root.show()
Downloads
├── Misc
│   ├── Pictures
│   │   └── photo2.jpg
│   └── Applications
│       └── Chrome.exe
├── Pictures
│   └── photo1.jpg
└── dummy
    └── Files
        └── file1.doc
>>> shift_nodes(
...     root,
...     ["Downloads/Misc/Pictures", "Applications", "Downloads/dummy"],
...     ["Downloads/Pictures", "Downloads/Applications", "Downloads/dummy"],
...     merge_leaves=True,
... )
>>> root.show()
Downloads
├── Misc
│   ├── Pictures
│   └── Applications
├── Pictures
│   ├── photo1.jpg
│   └── photo2.jpg
├── dummy
│   └── Files
├── Chrome.exe
└── file1.doc

In delete_children=True case, only the node is shifted without its accompanying children/descendants.

>>> root = str_to_tree(
... "Downloads\n"
... "├── Misc\n"
... "│   └── Applications\n"
... "│       └── Chrome.exe\n"
... "└── Pictures\n"
... "    └── photo1.jpg"
... )
>>> root.show()
Downloads
├── Misc
│   └── Applications
│       └── Chrome.exe
└── Pictures
    └── photo1.jpg
>>> shift_nodes(root, ["Applications"], ["Downloads/Applications"], delete_children=True)
>>> root.show()
Downloads
├── Misc
├── Pictures
│   └── photo1.jpg
└── Applications

Parameters:

Name Type Description Default
tree Node

tree to modify

required
from_paths List[str]

original paths to shift nodes from

required
to_paths List[str]

new paths to shift nodes to

required
sep str

path separator for input paths, applies to from_path and to_path

'/'
skippable bool

indicator to skip if from path is not found, defaults to False

False
overriding bool

indicator to override existing to path if there is clashes, defaults to False

False
merge_children bool

indicator to merge children and remove intermediate parent node, defaults to False

False
merge_leaves bool

indicator to merge leaf nodes and remove intermediate parent node(s), defaults to False

False
delete_children bool

indicator to shift node only without children, defaults to False

False
with_full_path bool

indicator to shift/copy node with full path in from_paths, results in faster search, defaults to False

False

copy_nodes

copy_nodes(
    tree,
    from_paths,
    to_paths,
    sep="/",
    skippable=False,
    overriding=False,
    merge_children=False,
    merge_leaves=False,
    delete_children=False,
    with_full_path=False,
)

Copy nodes from from_paths to to_paths in-place.

  • Creates intermediate nodes if to path is not present
  • Able to skip nodes if from path is not found, defaults to False (from-nodes must be found; not skippable).
  • Able to override existing node if it exists, defaults to False (to-nodes must not exist; not overridden).
  • Able to merge children and remove intermediate parent node, defaults to False (nodes are shifted; not merged).
  • Able to merge only leaf nodes and remove all intermediate nodes, defaults to False (nodes are shifted; not merged)
  • Able to copy node only and delete children, defaults to False (nodes are copied together with children).

For paths in from_paths and to_paths,

  • Path name can be with or without leading tree path separator symbol.

For paths in from_paths,

  • Path name can be partial path (trailing part of path) or node name.
  • If with_full_path=True, path name must be full path.
  • Path name must be unique to one node.

For paths in to_paths,

  • Path name must be full path.

If merge_children=True,

  • If to_path is not present, it copies children of from_path.
  • If to_path is present, and overriding=False, original and new children are merged.
  • If to_path is present and overriding=True, it behaves like overriding and only new children are retained.

If merge_leaves=True,

  • If to_path is not present, it copies leaves of from_path.
  • If to_path is present, and overriding=False, original children and leaves are merged.
  • If to_path is present and overriding=True, it behaves like overriding and only new leaves are retained.

Examples:

>>> from bigtree import list_to_tree, str_to_tree, copy_nodes
>>> root = list_to_tree(["Downloads/Pictures", "Downloads/photo1.jpg", "Downloads/file1.doc"])
>>> root.show()
Downloads
├── Pictures
├── photo1.jpg
└── file1.doc
>>> copy_nodes(
...     tree=root,
...     from_paths=["Downloads/photo1.jpg", "Downloads/file1.doc"],
...     to_paths=["Downloads/Pictures/photo1.jpg", "Downloads/Files/file1.doc"],
... )
>>> root.show()
Downloads
├── Pictures
│   └── photo1.jpg
├── photo1.jpg
├── file1.doc
└── Files
    └── file1.doc

In overriding case,

>>> root = str_to_tree(
... "Downloads\n"
... "├── Misc\n"
... "│   └── Pictures\n"
... "│       └── photo1.jpg\n"
... "└── Pictures\n"
... "    └── photo2.jpg"
... )
>>> root.show()
Downloads
├── Misc
│   └── Pictures
│       └── photo1.jpg
└── Pictures
    └── photo2.jpg
>>> copy_nodes(root, ["Downloads/Misc/Pictures"], ["Downloads/Pictures"], overriding=True)
>>> root.show()
Downloads
├── Misc
│   └── Pictures
│       └── photo1.jpg
└── Pictures
    └── photo1.jpg

In merge_children=True case, child nodes are copied instead of the parent node.

  • If the path already exists, child nodes are merged with existing children.
  • If same node is copied, the child nodes of the node are merged with the node's parent.
>>> root = str_to_tree(
... "Downloads\n"
... "├── Misc\n"
... "│   ├── Pictures\n"
... "│   │   └── photo2.jpg\n"
... "│   └── Applications\n"
... "│       └── Chrome.exe\n"
... "├── Pictures\n"
... "│   └── photo1.jpg\n"
... "└── dummy\n"
... "    └── Files\n"
... "        └── file1.doc"
... )
>>> root.show()
Downloads
├── Misc
│   ├── Pictures
│   │   └── photo2.jpg
│   └── Applications
│       └── Chrome.exe
├── Pictures
│   └── photo1.jpg
└── dummy
    └── Files
        └── file1.doc
>>> copy_nodes(
...     root,
...     ["Downloads/Misc/Pictures", "Applications", "Downloads/dummy"],
...     ["Downloads/Pictures", "Downloads/Applications", "Downloads/dummy"],
...     merge_children=True,
... )
>>> root.show()
Downloads
├── Misc
│   ├── Pictures
│   │   └── photo2.jpg
│   └── Applications
│       └── Chrome.exe
├── Pictures
│   ├── photo1.jpg
│   └── photo2.jpg
├── Chrome.exe
└── Files
    └── file1.doc

In merge_leaves=True case, leaf nodes are copied instead of the parent node.

  • If the path already exists, leaf nodes are merged with existing children.
  • If same node is copied, the leaf nodes of the node are merged with the node's parent.
>>> root = str_to_tree(
... "Downloads\n"
... "├── Misc\n"
... "│   ├── Pictures\n"
... "│   │   └── photo2.jpg\n"
... "│   └── Applications\n"
... "│       └── Chrome.exe\n"
... "├── Pictures\n"
... "│   └── photo1.jpg\n"
... "└── dummy\n"
... "    └── Files\n"
... "        └── file1.doc"
... )
>>> root.show()
Downloads
├── Misc
│   ├── Pictures
│   │   └── photo2.jpg
│   └── Applications
│       └── Chrome.exe
├── Pictures
│   └── photo1.jpg
└── dummy
    └── Files
        └── file1.doc
>>> copy_nodes(
...     root,
...     ["Downloads/Misc/Pictures", "Applications", "Downloads/dummy"],
...     ["Downloads/Pictures", "Downloads/Applications", "Downloads/dummy"],
...     merge_leaves=True,
... )
>>> root.show()
Downloads
├── Misc
│   ├── Pictures
│   │   └── photo2.jpg
│   └── Applications
│       └── Chrome.exe
├── Pictures
│   ├── photo1.jpg
│   └── photo2.jpg
├── dummy
│   └── Files
│       └── file1.doc
├── Chrome.exe
└── file1.doc

In delete_children=True case, only the node is copied without its accompanying children/descendants.

>>> root = str_to_tree(
... "Downloads\n"
... "├── Misc\n"
... "│   └── Applications\n"
... "│       └── Chrome.exe\n"
... "└── Pictures\n"
... "    └── photo1.jpg"
... )
>>> root.show()
Downloads
├── Misc
│   └── Applications
│       └── Chrome.exe
└── Pictures
    └── photo1.jpg
>>> copy_nodes(root, ["Applications"], ["Downloads/Applications"], delete_children=True)
>>> root.show()
Downloads
├── Misc
│   └── Applications
│       └── Chrome.exe
├── Pictures
│   └── photo1.jpg
└── Applications

Parameters:

Name Type Description Default
tree Node

tree to modify

required
from_paths List[str]

original paths to shift nodes from

required
to_paths List[str]

new paths to shift nodes to

required
sep str

path separator for input paths, applies to from_path and to_path

'/'
skippable bool

indicator to skip if from path is not found, defaults to False

False
overriding bool

indicator to override existing to path if there is clashes, defaults to False

False
merge_children bool

indicator to merge children and remove intermediate parent node, defaults to False

False
merge_leaves bool

indicator to merge leaf nodes and remove intermediate parent node(s), defaults to False

False
delete_children bool

indicator to copy node only without children, defaults to False

False
with_full_path bool

indicator to shift/copy node with full path in from_paths, results in faster search, defaults to False

False

shift_and_replace_nodes

shift_and_replace_nodes(
    tree,
    from_paths,
    to_paths,
    sep="/",
    skippable=False,
    delete_children=False,
    with_full_path=False,
)

Shift nodes from from_paths to replace to_paths in-place.

  • Creates intermediate nodes if to path is not present
  • Able to skip nodes if from path is not found, defaults to False (from-nodes must be found; not skippable).
  • Able to shift node only and delete children, defaults to False (nodes are shifted together with children).

For paths in from_paths and to_paths,

  • Path name can be with or without leading tree path separator symbol.

For paths in from_paths,

  • Path name can be partial path (trailing part of path) or node name.
  • If with_full_path=True, path name must be full path.
  • Path name must be unique to one node.

For paths in to_paths,

  • Path name must be full path.
  • Path must exist, node-to-be-replaced must be present.

Examples:

>>> from bigtree import str_to_tree, shift_and_replace_nodes
>>> root = str_to_tree(
... "Downloads\n"
... "├── Pictures\n"
... "│   └── photo1.jpg\n"
... "└── Misc\n"
... "    └── dummy"
... )
>>> root.show()
Downloads
├── Pictures
│   └── photo1.jpg
└── Misc
    └── dummy
>>> shift_and_replace_nodes(root, ["Downloads/Pictures"], ["Downloads/Misc/dummy"])
>>> root.show()
Downloads
└── Misc
    └── Pictures
        └── photo1.jpg

In delete_children=True case, only the node is shifted without its accompanying children/descendants.

>>> root = str_to_tree(
... "Downloads\n"
... "├── Pictures\n"
... "│   └── photo1.jpg\n"
... "└── Misc\n"
... "    └── dummy"
... )
>>> root.show()
Downloads
├── Pictures
│   └── photo1.jpg
└── Misc
    └── dummy
>>> shift_and_replace_nodes(root, ["Downloads/Pictures"], ["Downloads/Misc/dummy"], delete_children=True)
>>> root.show()
Downloads
└── Misc
    └── Pictures

Parameters:

Name Type Description Default
tree Node

tree to modify

required
from_paths List[str]

original paths to shift nodes from

required
to_paths List[str]

new paths to shift nodes to

required
sep str

path separator for input paths, applies to from_path and to_path

'/'
skippable bool

indicator to skip if from path is not found, defaults to False

False
delete_children bool

indicator to shift node only without children, defaults to False

False
with_full_path bool

indicator to shift/copy node with full path in from_paths, results in faster search, defaults to False

False

copy_nodes_from_tree_to_tree

copy_nodes_from_tree_to_tree(
    from_tree,
    to_tree,
    from_paths,
    to_paths,
    sep="/",
    skippable=False,
    overriding=False,
    merge_children=False,
    merge_leaves=False,
    delete_children=False,
    with_full_path=False,
)

Copy nodes from from_paths to to_paths in-place.

  • Creates intermediate nodes if to path is not present
  • Able to skip nodes if from path is not found, defaults to False (from-nodes must be found; not skippable).
  • Able to override existing node if it exists, defaults to False (to-nodes must not exist; not overridden).
  • Able to merge children and remove intermediate parent node, defaults to False (nodes are shifted; not merged).
  • Able to merge only leaf nodes and remove all intermediate nodes, defaults to False (nodes are shifted; not merged)
  • Able to copy node only and delete children, defaults to False (nodes are copied together with children).

For paths in from_paths and to_paths,

  • Path name can be with or without leading tree path separator symbol.

For paths in from_paths,

  • Path name can be partial path (trailing part of path) or node name.
  • If with_full_path=True, path name must be full path.
  • Path name must be unique to one node.

For paths in to_paths,

  • Path name must be full path.

If merge_children=True,

  • If to_path is not present, it copies children of from_path
  • If to_path is present, and overriding=False, original and new children are merged
  • If to_path is present and overriding=True, it behaves like overriding and only new leaves are retained.

If merge_leaves=True,

  • If to_path is not present, it copies leaves of from_path.
  • If to_path is present, and overriding=False, original children and leaves are merged.
  • If to_path is present and overriding=True, it behaves like overriding and only new leaves are retained.

Examples:

>>> from bigtree import Node, str_to_tree, copy_nodes_from_tree_to_tree
>>> root = str_to_tree(
... "Downloads\n"
... "├── file1.doc\n"
... "├── Pictures\n"
... "│   └── photo1.jpg\n"
... "└── Misc\n"
... "    └── dummy\n"
... "        └── photo2.jpg"
... )
>>> root.show()
Downloads
├── file1.doc
├── Pictures
│   └── photo1.jpg
└── Misc
    └── dummy
        └── photo2.jpg
>>> root_other = Node("Documents")
>>> copy_nodes_from_tree_to_tree(
...     from_tree=root,
...     to_tree=root_other,
...     from_paths=["Downloads/Pictures", "Downloads/Misc"],
...     to_paths=["Documents/Pictures", "Documents/New Misc/Misc"],
... )
>>> root_other.show()
Documents
├── Pictures
│   └── photo1.jpg
└── New Misc
    └── Misc
        └── dummy
            └── photo2.jpg

In overriding case,

>>> root_other = str_to_tree(
... "Documents\n"
... "└── Pictures\n"
... "    └── photo3.jpg"
... )
>>> root_other.show()
Documents
└── Pictures
    └── photo3.jpg
>>> copy_nodes_from_tree_to_tree(
...     root,
...     root_other,
...     ["Downloads/Pictures", "Downloads/Misc"],
...     ["Documents/Pictures", "Documents/Misc"],
...     overriding=True,
... )
>>> root_other.show()
Documents
├── Pictures
│   └── photo1.jpg
└── Misc
    └── dummy
        └── photo2.jpg

In merge_children=True case, child nodes are copied instead of the parent node.

  • If the path already exists, child nodes are merged with existing children.
>>> root_other = str_to_tree(
... "Documents\n"
... "└── Pictures\n"
... "    └── photo3.jpg"
... )
>>> root_other.show()
Documents
└── Pictures
    └── photo3.jpg
>>> copy_nodes_from_tree_to_tree(
...     root,
...     root_other,
...     ["Downloads/Pictures", "Downloads/Misc"],
...     ["Documents/Pictures", "Documents/Misc"],
...     merge_children=True,
... )
>>> root_other.show()
Documents
├── Pictures
│   ├── photo3.jpg
│   └── photo1.jpg
└── dummy
    └── photo2.jpg

In merge_leaves=True case, leaf nodes are copied instead of the parent node.

  • If the path already exists, leaf nodes are merged with existing children.
>>> root_other = str_to_tree(
... "Documents\n"
... "└── Pictures\n"
... "    └── photo3.jpg"
... )
>>> root_other.show()
Documents
└── Pictures
    └── photo3.jpg
>>> copy_nodes_from_tree_to_tree(
...     root,
...     root_other,
...     ["Downloads/Pictures", "Downloads/Misc"],
...     ["Documents/Pictures", "Documents/Misc"],
...     merge_leaves=True,
... )
>>> root_other.show()
Documents
├── Pictures
│   ├── photo3.jpg
│   └── photo1.jpg
└── photo2.jpg

In delete_children=True case, only the node is copied without its accompanying children/descendants.

>>> root_other = Node("Documents")
>>> root_other.show()
Documents
>>> copy_nodes_from_tree_to_tree(
...     root,
...     root_other,
...     ["Downloads/Pictures", "Downloads/Misc"],
...     ["Documents/Pictures", "Documents/Misc"],
...     delete_children=True,
... )
>>> root_other.show()
Documents
├── Pictures
└── Misc

Parameters:

Name Type Description Default
from_tree Node

tree to copy nodes from

required
to_tree Node

tree to copy nodes to

required
from_paths List[str]

original paths to shift nodes from

required
to_paths List[str]

new paths to shift nodes to

required
sep str

path separator for input paths, applies to from_path and to_path

'/'
skippable bool

indicator to skip if from path is not found, defaults to False

False
overriding bool

indicator to override existing to path if there is clashes, defaults to False

False
merge_children bool

indicator to merge children and remove intermediate parent node, defaults to False

False
merge_leaves bool

indicator to merge leaf nodes and remove intermediate parent node(s), defaults to False

False
delete_children bool

indicator to copy node only without children, defaults to False

False
with_full_path bool

indicator to shift/copy node with full path in from_paths, results in faster search, defaults to False

False

copy_and_replace_nodes_from_tree_to_tree

copy_and_replace_nodes_from_tree_to_tree(
    from_tree,
    to_tree,
    from_paths,
    to_paths,
    sep="/",
    skippable=False,
    delete_children=False,
    with_full_path=False,
)

Copy nodes from from_paths to replace to_paths in-place.

  • Creates intermediate nodes if to path is not present
  • Able to skip nodes if from path is not found, defaults to False (from-nodes must be found; not skippable).
  • Able to copy node only and delete children, defaults to False (nodes are copied together with children).

For paths in from_paths and to_paths,

  • Path name can be with or without leading tree path separator symbol.

For paths in from_paths,

  • Path name can be partial path (trailing part of path) or node name.
  • If with_full_path=True, path name must be full path.
  • Path name must be unique to one node.

For paths in to_paths,

  • Path name must be full path.
  • Path must exist, node-to-be-replaced must be present.

Examples:

>>> from bigtree import str_to_tree, copy_and_replace_nodes_from_tree_to_tree
>>> root = str_to_tree(
... "Downloads\n"
... "├── file1.doc\n"
... "├── Pictures\n"
... "│   └── photo1.jpg\n"
... "└── Misc\n"
... "    └── dummy\n"
... "        └── photo2.jpg"
... )
>>> root.show()
Downloads
├── file1.doc
├── Pictures
│   └── photo1.jpg
└── Misc
    └── dummy
        └── photo2.jpg
>>> root_other = str_to_tree(
... "Documents\n"
... "├── Pictures2\n"
... "│   └── photo2.jpg\n"
... "└── Misc2"
... )
>>> root_other.show()
Documents
├── Pictures2
│   └── photo2.jpg
└── Misc2
>>> copy_and_replace_nodes_from_tree_to_tree(
...     from_tree=root,
...     to_tree=root_other,
...     from_paths=["Downloads/Pictures", "Downloads/Misc"],
...     to_paths=["Documents/Pictures2/photo2.jpg", "Documents/Misc2"],
... )
>>> root_other.show()
Documents
├── Pictures2
│   └── Pictures
│       └── photo1.jpg
└── Misc
    └── dummy
        └── photo2.jpg

In delete_children=True case, only the node is copied without its accompanying children/descendants.

>>> root_other = str_to_tree(
... "Documents\n"
... "├── Pictures2\n"
... "│   └── photo2.jpg\n"
... "└── Misc2"
... )
>>> root_other.show()
Documents
├── Pictures2
│   └── photo2.jpg
└── Misc2
>>> copy_and_replace_nodes_from_tree_to_tree(
...     from_tree=root,
...     to_tree=root_other,
...     from_paths=["Downloads/Pictures", "Downloads/Misc"],
...     to_paths=["Documents/Pictures2/photo2.jpg", "Documents/Misc2"],
...     delete_children=True,
... )
>>> root_other.show()
Documents
├── Pictures2
│   └── Pictures
└── Misc

Parameters:

Name Type Description Default
from_tree Node

tree to copy nodes from

required
to_tree Node

tree to copy nodes to

required
from_paths List[str]

original paths to shift nodes from

required
to_paths List[str]

new paths to shift nodes to

required
sep str

path separator for input paths, applies to from_path and to_path

'/'
skippable bool

indicator to skip if from path is not found, defaults to False

False
delete_children bool

indicator to copy node only without children, defaults to False

False
with_full_path bool

indicator to shift/copy node with full path in from_paths, results in faster search, defaults to False

False

copy_or_shift_logic

copy_or_shift_logic(
    tree,
    from_paths,
    to_paths,
    sep="/",
    copy=False,
    skippable=False,
    overriding=False,
    merge_children=False,
    merge_leaves=False,
    delete_children=False,
    to_tree=None,
    with_full_path=False,
)

Shift or copy nodes from from_paths to to_paths in-place.

  • Creates intermediate nodes if to path is not present
  • Able to copy node, defaults to False (nodes are shifted; not copied).
  • Able to skip nodes if from path is not found, defaults to False (from-nodes must be found; not skippable)
  • Able to override existing node if it exists, defaults to False (to-nodes must not exist; not overridden)
  • Able to merge children and remove intermediate parent node, defaults to False (nodes are shifted; not merged)
  • Able to merge only leaf nodes and remove all intermediate nodes, defaults to False (nodes are shifted; not merged)
  • Able to shift/copy node only and delete children, defaults to False (nodes are shifted/copied together with children).
  • Able to shift/copy nodes from one tree to another tree, defaults to None (shifting/copying happens within same tree)

For paths in from_paths and to_paths,

  • Path name can be with or without leading tree path separator symbol.

For paths in from_paths,

  • Path name can be partial path (trailing part of path) or node name.
  • If with_full_path=True, path name must be full path.
  • Path name must be unique to one node.

For paths in to_paths,

  • Path name must be full path.
  • Can set to empty string or None to delete the path in from_paths, note that copy must be set to False.

If merge_children=True,

  • If to_path is not present, it shifts/copies children of from_path.
  • If to_path is present, and overriding=False, original and new children are merged.
  • If to_path is present and overriding=True, it behaves like overriding and only new children are retained.

If merge_leaves=True,

  • If to_path is not present, it shifts/copies leaves of from_path.
  • If to_path is present, and overriding=False, original children and leaves are merged.
  • If to_path is present and overriding=True, it behaves like overriding and only new leaves are retained, original non-leaf nodes in from_path are retained.

Parameters:

Name Type Description Default
tree Node

tree to modify

required
from_paths List[str]

original paths to shift nodes from

required
to_paths List[str]

new paths to shift nodes to

required
sep str

path separator for input paths, applies to from_path and to_path

'/'
copy bool

indicator to copy node, defaults to False

False
skippable bool

indicator to skip if from path is not found, defaults to False

False
overriding bool

indicator to override existing to path if there is clashes, defaults to False

False
merge_children bool

indicator to merge children and remove intermediate parent node, defaults to False

False
merge_leaves bool

indicator to merge leaf nodes and remove intermediate parent node(s), defaults to False

False
delete_children bool

indicator to shift/copy node only without children, defaults to False

False
to_tree Node

tree to copy to, defaults to None

None
with_full_path bool

indicator to shift/copy node with full path in from_paths, results in faster search, defaults to False

False

replace_logic

replace_logic(
    tree,
    from_paths,
    to_paths,
    sep="/",
    copy=False,
    skippable=False,
    delete_children=False,
    to_tree=None,
    with_full_path=False,
)

Shift or copy nodes from from_paths to replace to_paths in-place.

  • Creates intermediate nodes if to path is not present
  • Able to copy node, defaults to False (nodes are shifted; not copied).
  • Able to skip nodes if from path is not found, defaults to False (from-nodes must be found; not skippable)
  • Able to replace node only and delete children, defaults to False (nodes are shifted/copied together with children).
  • Able to shift/copy nodes from one tree to another tree, defaults to None (shifting/copying happens within same tree)

For paths in from_paths and to_paths,

  • Path name can be with or without leading tree path separator symbol.

For paths in from_paths,

  • Path name can be partial path (trailing part of path) or node name.
  • If with_full_path=True, path name must be full path.
  • Path name must be unique to one node.

For paths in to_paths,

  • Path name must be full path.
  • Path must exist, node-to-be-replaced must be present.

Parameters:

Name Type Description Default
tree Node

tree to modify

required
from_paths List[str]

original paths to shift nodes from

required
to_paths List[str]

new paths to shift nodes to

required
sep str

path separator for input paths, applies to from_path and to_path

'/'
copy bool

indicator to copy node, defaults to False

False
skippable bool

indicator to skip if from path is not found, defaults to False

False
delete_children bool

indicator to shift/copy node only without children, defaults to False

False
to_tree Node

tree to copy to, defaults to None

None
with_full_path bool

indicator to shift/copy node with full path in from_paths, results in faster search, defaults to False

False