A mutable, self-balancing interval tree data structure that enables efficient querying of intervals by point, range overlap, or range envelopment
—
Native Python integration through magic methods enabling slice notation, iteration, membership testing, and standard container operations. IntervalTree implements the MutableSet interface and provides intuitive Pythonic usage patterns.
Use Python slice notation for intuitive interval querying and modification.
def __getitem__(self, index):
"""
Query intervals using slice notation.
Parameters:
- index: Point (int/float) for point query, or slice object for range query
Returns:
set: Set of overlapping intervals
Usage:
- tree[point] -> intervals containing point
- tree[start:stop] -> intervals overlapping [start, stop)
Time Complexity: O(k*log(n) + m) where m is result size, k is complexity factor
"""
def __setitem__(self, index, value):
"""
Add interval using slice notation.
Parameters:
- index: slice object (start:stop)
- value: Data for the new interval
Usage:
- tree[start:stop] = data -> adds Interval(start, stop, data)
Time Complexity: O(log n)
"""
def __delitem__(self, point):
"""
Remove all intervals containing point.
Parameters:
- point: Point value
Usage:
- del tree[point] -> removes all intervals containing point
"""Standard Python container operations for length, membership, and iteration.
def __len__(self):
"""
Get number of intervals in tree.
Returns:
int: Number of intervals
Usage: len(tree)
Time Complexity: O(1)
"""
def __contains__(self, item):
"""
Test membership of exact interval.
Parameters:
- item: Interval object to test
Returns:
bool: True if exact interval exists in tree
Usage: interval in tree
Time Complexity: O(1)
"""
def containsi(self, begin, end, data=None):
"""
Test membership by interval values.
Parameters:
- begin: Lower bound
- end: Upper bound
- data: Data payload
Returns:
bool: True if interval with these values exists
Usage: tree.containsi(0, 10, "data")
Time Complexity: O(1)
"""Iteration over intervals with guaranteed order.
def __iter__(self):
"""
Iterate over all intervals in sorted order.
Returns:
iterator: Iterator yielding intervals sorted by begin, then end, then data
Usage:
- for interval in tree: ...
- list(tree)
- sorted(tree)
Time Complexity: O(1) to create iterator, O(n) to consume all
"""
def iter(self):
"""Alias for __iter__()."""Tree comparison operations.
def __eq__(self, other):
"""
Test equality between trees.
Parameters:
- other: IntervalTree to compare
Returns:
bool: True if trees contain identical intervals
Usage: tree1 == tree2
Time Complexity: O(n) if sizes equal, O(1) otherwise
"""String formatting for debugging and display.
def __repr__(self):
"""
Detailed string representation.
Returns:
str: String showing all intervals in tree
Usage: repr(tree), str(tree)
"""
def __str__(self):
"""Alias for __repr__()."""Serialization support for saving and loading trees.
def __reduce__(self):
"""
Support for pickle serialization.
Returns:
tuple: Pickle reconstruction data
Usage: pickle.dump(tree, file)
"""from intervaltree import Interval, IntervalTree
# Create tree
tree = IntervalTree([
Interval(0, 10, "first"),
Interval(5, 15, "second"),
Interval(20, 30, "third")
])
# Point queries using slice notation
overlapping = tree[7] # Find intervals containing point 7
print(overlapping) # {Interval(0, 10, 'first'), Interval(5, 15, 'second')}
# Range queries using slice notation
overlapping = tree[8:25] # Find intervals overlapping [8, 25)
print(overlapping) # {Interval(0, 10, 'first'), Interval(5, 15, 'second'), Interval(20, 30, 'third')}
# Empty result
overlapping = tree[50] # No intervals contain point 50
print(overlapping) # set()from intervaltree import Interval, IntervalTree
tree = IntervalTree()
# Add intervals using slice notation
tree[0:10] = "first interval"
tree[15:25] = "second interval"
tree[30:40] = "third interval"
print(f"Tree now contains {len(tree)} intervals")
# Equivalent to:
# tree.add(Interval(0, 10, "first interval"))
# tree.add(Interval(15, 25, "second interval"))
# tree.add(Interval(30, 40, "third interval"))
# Delete all intervals containing point 20
del tree[20] # Removes interval [15, 25)
print(f"After deletion: {len(tree)} intervals")from intervaltree import Interval, IntervalTree
tree = IntervalTree([
Interval(0, 10, "a"),
Interval(15, 25, "b"),
Interval(30, 40, "c")
])
# Length
print(f"Tree contains {len(tree)} intervals")
# Membership testing
test_interval = Interval(15, 25, "b")
if test_interval in tree:
print("Interval found in tree")
# Test with different data (will not match)
test_interval2 = Interval(15, 25, "different")
if test_interval2 not in tree:
print("Interval with different data not found")
# Membership by values
if tree.containsi(0, 10, "a"):
print("Interval (0, 10, 'a') exists")
# Boolean evaluation (empty tree is falsy)
empty_tree = IntervalTree()
if not empty_tree:
print("Empty tree evaluates to False")
if tree:
print("Non-empty tree evaluates to True")from intervaltree import Interval, IntervalTree
tree = IntervalTree([
Interval(20, 30, "third"),
Interval(0, 10, "first"),
Interval(10, 20, "second")
])
# Basic iteration (automatically sorted)
print("All intervals:")
for interval in tree:
print(f" {interval}")
# Convert to list
interval_list = list(tree)
print(f"List of {len(interval_list)} intervals")
# Iterate with enumeration
print("Numbered intervals:")
for i, interval in enumerate(tree):
print(f" {i+1}: {interval}")
# Filter during iteration
print("Intervals with begin >= 10:")
for interval in tree:
if interval.begin >= 10:
print(f" {interval}")
# List comprehension
data_values = [interval.data for interval in tree]
print(f"Data values: {data_values}")from intervaltree import Interval, IntervalTree
# Create identical trees
tree1 = IntervalTree([
Interval(0, 10, "a"),
Interval(15, 25, "b")
])
tree2 = IntervalTree([
Interval(15, 25, "b"), # Order doesn't matter for equality
Interval(0, 10, "a")
])
tree3 = IntervalTree([
Interval(0, 10, "a"),
Interval(15, 25, "different") # Different data
])
# Equality testing
print(tree1 == tree2) # True - same intervals
print(tree1 == tree3) # False - different data in second interval
# Inequality
print(tree1 != tree3) # True
# Empty trees
empty1 = IntervalTree()
empty2 = IntervalTree()
print(empty1 == empty2) # True - both emptyfrom intervaltree import Interval, IntervalTree
tree = IntervalTree([
Interval(0, 10, "first"),
Interval(15, 25, "second")
])
# String representation
print(f"Tree: {tree}")
# Output: IntervalTree([Interval(0, 10, 'first'), Interval(15, 25, 'second')])
print(f"Repr: {repr(tree)}")
# Same as above
# Empty tree representation
empty = IntervalTree()
print(f"Empty tree: {empty}")
# Output: IntervalTree()
# Useful for debugging
print(f"Tree state: {tree}")
print(f"Tree length: {len(tree)}")
print(f"Tree empty: {len(tree) == 0}")import pickle
from intervaltree import Interval, IntervalTree
# Create tree
tree = IntervalTree([
Interval(0, 10, "data1"),
Interval(15, 25, "data2")
])
# Serialize to bytes
pickled_data = pickle.dumps(tree)
print(f"Pickled size: {len(pickled_data)} bytes")
# Deserialize
restored_tree = pickle.loads(pickled_data)
print(f"Restored tree: {restored_tree}")
print(f"Trees equal: {tree == restored_tree}")
# File-based pickling
with open('/tmp/tree.pkl', 'wb') as f:
pickle.dump(tree, f)
with open('/tmp/tree.pkl', 'rb') as f:
loaded_tree = pickle.load(f)
print(f"Loaded from file: {loaded_tree == tree}")from intervaltree import Interval, IntervalTree
# Create tree for advanced examples
tree = IntervalTree([
Interval(i, i+10, f"interval_{i}") for i in range(0, 100, 15)
])
# Use with built-in functions
print(f"Number of intervals: {len(tree)}")
print(f"Tree is empty: {not tree}")
# Sorting (already sorted, but demonstrates compatibility)
sorted_intervals = sorted(tree, key=lambda x: x.data)
# Filtering
long_intervals = [i for i in tree if i.length() > 5]
print(f"Long intervals: {len(long_intervals)}")
# Set operations (using standard Python set methods since IntervalTree is a MutableSet)
tree2 = IntervalTree([Interval(5, 15, "overlap")])
# MutableSet interface methods work
tree_copy = tree.copy()
tree_copy.discard(Interval(0, 10, "interval_0"))
# Use in set comprehensions
data_set = {interval.data for interval in tree}
print(f"Unique data values: {len(data_set)}")
# Compatible with any/all
has_long_intervals = any(i.length() > 20 for i in tree)
all_have_data = all(i.data is not None for i in tree)
print(f"Has long intervals: {has_long_intervals}")
print(f"All have data: {all_have_data}")Install with Tessl CLI
npx tessl i tessl/pypi-intervaltree