spekk.trees.treelens.TreeLens#

class spekk.trees.treelens.TreeLens(tree: Mapping[Any, Mapping[Any, Tree] | Sequence[Tree] | Any] | Sequence[Mapping[Any, Tree] | Sequence[Tree] | Any] | Any = ())[source]#

Bases: object

A functional interface to a Tree.

A lens is an object in functional programming (FP) that allows you to access and modify a value in a nested structure in an immutable way.

__init__(tree: Mapping[Any, Mapping[Any, Tree] | Sequence[Tree] | Any] | Sequence[Mapping[Any, Tree] | Sequence[Tree] | Any] | Any = ())[source]#

Methods

__init__([tree])

copy_with(tree)

Return a copy of this object with the given tree.

get(path)

Get the value or subtree at the given path.

has_subtree(path)

Return True if the given path exists in the tree.

is_leaf(tree)

Return True if the given tree is a leaf.

prune_empty_branches([is_leaf])

Remove all empty subtrees.

remove_subtree(path)

Remove the value or subtree at the given path.

set(value, path)

Set the value or subtree at the given path.

update_leaves(f[, path])

See update_leaves().

update_subtree(f, path)

Update the value or subtree at the given path.

Attributes

at

Interface for working on subtrees.

property at: _TreeNavigator#

Interface for working on subtrees. This is a convenience method that provides the same functionality as set(…) and update_subtree(…), but with a (potentially) more readable syntax.

>>> tree = TreeLens({"a": {"b": [1, 2, 3]}, "d": [3]})

It can be used to set the value at the given path: >>> tree.at[“a”, “b”, 1].set(5) TreeLens({‘a’: {‘b’: [1, 5, 3]}, ‘d’: [3]})

Or update it, given a function: >>> tree.at[“a”, “b”, 1].update(lambda x: x+10) TreeLens({‘a’: {‘b’: [1, 12, 3]}, ‘d’: [3]})

copy_with(tree: Mapping[Any, Mapping[Any, Tree] | Sequence[Tree] | Any] | Sequence[Mapping[Any, Tree] | Sequence[Tree] | Any] | Any) TSelf[source]#

Return a copy of this object with the given tree.

get(path: Sequence[Any]) TSelf[source]#

Get the value or subtree at the given path.

>>> tree = TreeLens({"a": {"b": [1, 2, 3]}, "d": [3]})
>>> tree.get(["a", "b"])
TreeLens([1, 2, 3])
>>> tree.get(["a", "b", 1])
TreeLens(2)
has_subtree(path: Sequence[Any]) bool[source]#

Return True if the given path exists in the tree.

>>> tree = TreeLens({"a": {"b": [1, 2, 3]}})
>>> tree.has_subtree(["a", "b", 1])
True
>>> tree.has_subtree(["a", "c"])
False
is_leaf(tree: Mapping[Any, Mapping[Any, Tree] | Sequence[Tree] | Any] | Sequence[Mapping[Any, Tree] | Sequence[Tree] | Any] | Any) bool[source]#

Return True if the given tree is a leaf.

By default, this is True if the tree has not been registered with the treedef registry, but should be overridden for more specialized trees.

prune_empty_branches(is_leaf: Callable[[Mapping[Any, Mapping[Any, Tree] | Sequence[Tree] | Any] | Sequence[Mapping[Any, Tree] | Sequence[Tree] | Any] | Any], bool] | None = None) TSelf | Mapping[Any, Mapping[Any, Tree] | Sequence[Tree] | Any] | Sequence[Mapping[Any, Tree] | Sequence[Tree] | Any] | Any[source]#

Remove all empty subtrees.

May be called as a static method where self is a Tree.

remove_subtree(path: Sequence[Any]) TSelf[source]#

Remove the value or subtree at the given path.

>>> tree = TreeLens({"a": {"b": [1, 2, 3]}, "d": [3]})
>>> tree.remove_subtree(["a", "b", 1])
TreeLens({'a': {'b': [1, 3]}, 'd': [3]})
set(value: Any, path: Sequence[Any]) TSelf[source]#

Set the value or subtree at the given path.

>>> tree = TreeLens({"a": {"b": [1, 2, 3]}, "d": [3]})
>>> tree.set(5, ["a", "b", 1])
TreeLens({'a': {'b': [1, 5, 3]}, 'd': [3]})
update_leaves(f: Callable, path: Sequence[Any] = ()) TSelf[source]#

See update_leaves().

update_subtree(f: Callable, path: Sequence[Any]) TSelf[source]#

Update the value or subtree at the given path.

>>> tree = TreeLens({"a":{"b": [1, 2, 3]}, "d":[3]})
>>> tree.update_subtree(lambda x: x + 10, ["a", "b", 1])
TreeLens({'a': {'b': [1, 12, 3]}, 'd': [3]})