Multidimensional Trees ====================== **Application**: Tree nodes should be hooked-up in multiple trees. An anytree node is only able to be part of **one** tree, not multiple. The following example shows how to handle this. **Example**: 4 objects `A`, `B`, `C` and `D` shall be part of the trees `X` and `Y`. The objects `A`, `B`, `C` and `D` are instances of a class `Item`. It is *not* a tree node. It just contains references `x` and `y` to the node representations in the corresponding trees. >>> class Item: ... def __init__(self, name): ... self.name = name ... self.x = None ... self.y = None ... def __repr__(self): ... return "Item(%r)" % self.name >>> a = Item('A') >>> b = Item('B') >>> c = Item('C') >>> d = Item('D') The tree nodes just contain the reference to `item` and take care of the proper reference, by using the attach/detach protocol. >>> from anytree import NodeMixin, RenderTree >>> class NodeX(NodeMixin): ... def __init__(self, item, parent=None): ... self.item = item ... self.parent = parent ... def _pre_detach(self, parent): ... self.item.x = None ... def _pre_attach(self, parent): ... self.item.x = self >>> class NodeY(NodeMixin): ... def __init__(self, item, parent=None): ... self.item = item ... self.parent = parent ... def _pre_detach(self, parent): ... self.item.y = None ... def _pre_attach(self, parent): ... self.item.y = self Tree generation is simple: >>> # X >>> xa = NodeX(a) >>> xb = NodeX(b, parent=xa) >>> xc = NodeX(c, parent=xa) >>> xd = NodeX(d, parent=xc) >>> # Y >>> yd = NodeY(d) >>> yc = NodeY(c, parent=yd) >>> yb = NodeY(b, parent=yd) >>> ya = NodeY(a, parent=yb) All tree functions as rendering and exporting can be used as usual: >>> for row in RenderTree(xa): ... print("%s%s" % (row.pre, row.node.item)) Item('A') ├── Item('B') └── Item('C') └── Item('D') >>> for row in RenderTree(yd): ... print("%s%s" % (row.pre, row.node.item)) Item('D') ├── Item('C') └── Item('B') └── Item('A')