A self-balancing BST — rotations keep it height-balanced.
def bst(root, val):
# insert / search / traverse
if root is None:
return Node(val) # Inserted/Found
if val < root.val:
root.left = bst(root.left, val)
else:
root.right = bst(root.right, val)
# traversal order
visit(root.val) # Visit
Dynamically typed and interpreted — every comparison and swap is dispatched by the interpreter at run time, so tight loops run roughly 10–100× slower than compiled C/C++. Unbeatable for learning the idea with the least code; not what you reach for when the inner loop is the bottleneck.