0
# Python Integration
1
2
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.
3
4
## Capabilities
5
6
### Slice Notation Access
7
8
Use Python slice notation for intuitive interval querying and modification.
9
10
```python { .api }
11
def __getitem__(self, index):
12
"""
13
Query intervals using slice notation.
14
15
Parameters:
16
- index: Point (int/float) for point query, or slice object for range query
17
18
Returns:
19
set: Set of overlapping intervals
20
21
Usage:
22
- tree[point] -> intervals containing point
23
- tree[start:stop] -> intervals overlapping [start, stop)
24
25
Time Complexity: O(k*log(n) + m) where m is result size, k is complexity factor
26
"""
27
28
def __setitem__(self, index, value):
29
"""
30
Add interval using slice notation.
31
32
Parameters:
33
- index: slice object (start:stop)
34
- value: Data for the new interval
35
36
Usage:
37
- tree[start:stop] = data -> adds Interval(start, stop, data)
38
39
Time Complexity: O(log n)
40
"""
41
42
def __delitem__(self, point):
43
"""
44
Remove all intervals containing point.
45
46
Parameters:
47
- point: Point value
48
49
Usage:
50
- del tree[point] -> removes all intervals containing point
51
"""
52
```
53
54
### Container Interface
55
56
Standard Python container operations for length, membership, and iteration.
57
58
```python { .api }
59
def __len__(self):
60
"""
61
Get number of intervals in tree.
62
63
Returns:
64
int: Number of intervals
65
66
Usage: len(tree)
67
68
Time Complexity: O(1)
69
"""
70
71
def __contains__(self, item):
72
"""
73
Test membership of exact interval.
74
75
Parameters:
76
- item: Interval object to test
77
78
Returns:
79
bool: True if exact interval exists in tree
80
81
Usage: interval in tree
82
83
Time Complexity: O(1)
84
"""
85
86
def containsi(self, begin, end, data=None):
87
"""
88
Test membership by interval values.
89
90
Parameters:
91
- begin: Lower bound
92
- end: Upper bound
93
- data: Data payload
94
95
Returns:
96
bool: True if interval with these values exists
97
98
Usage: tree.containsi(0, 10, "data")
99
100
Time Complexity: O(1)
101
"""
102
```
103
104
### Iterator Interface
105
106
Iteration over intervals with guaranteed order.
107
108
```python { .api }
109
def __iter__(self):
110
"""
111
Iterate over all intervals in sorted order.
112
113
Returns:
114
iterator: Iterator yielding intervals sorted by begin, then end, then data
115
116
Usage:
117
- for interval in tree: ...
118
- list(tree)
119
- sorted(tree)
120
121
Time Complexity: O(1) to create iterator, O(n) to consume all
122
"""
123
124
def iter(self):
125
"""Alias for __iter__()."""
126
```
127
128
### Equality and Comparison
129
130
Tree comparison operations.
131
132
```python { .api }
133
def __eq__(self, other):
134
"""
135
Test equality between trees.
136
137
Parameters:
138
- other: IntervalTree to compare
139
140
Returns:
141
bool: True if trees contain identical intervals
142
143
Usage: tree1 == tree2
144
145
Time Complexity: O(n) if sizes equal, O(1) otherwise
146
"""
147
```
148
149
### String Representation
150
151
String formatting for debugging and display.
152
153
```python { .api }
154
def __repr__(self):
155
"""
156
Detailed string representation.
157
158
Returns:
159
str: String showing all intervals in tree
160
161
Usage: repr(tree), str(tree)
162
"""
163
164
def __str__(self):
165
"""Alias for __repr__()."""
166
```
167
168
### Pickling Support
169
170
Serialization support for saving and loading trees.
171
172
```python { .api }
173
def __reduce__(self):
174
"""
175
Support for pickle serialization.
176
177
Returns:
178
tuple: Pickle reconstruction data
179
180
Usage: pickle.dump(tree, file)
181
"""
182
```
183
184
## Usage Examples
185
186
### Slice Notation Queries
187
188
```python
189
from intervaltree import Interval, IntervalTree
190
191
# Create tree
192
tree = IntervalTree([
193
Interval(0, 10, "first"),
194
Interval(5, 15, "second"),
195
Interval(20, 30, "third")
196
])
197
198
# Point queries using slice notation
199
overlapping = tree[7] # Find intervals containing point 7
200
print(overlapping) # {Interval(0, 10, 'first'), Interval(5, 15, 'second')}
201
202
# Range queries using slice notation
203
overlapping = tree[8:25] # Find intervals overlapping [8, 25)
204
print(overlapping) # {Interval(0, 10, 'first'), Interval(5, 15, 'second'), Interval(20, 30, 'third')}
205
206
# Empty result
207
overlapping = tree[50] # No intervals contain point 50
208
print(overlapping) # set()
209
```
210
211
### Slice Notation Modification
212
213
```python
214
from intervaltree import Interval, IntervalTree
215
216
tree = IntervalTree()
217
218
# Add intervals using slice notation
219
tree[0:10] = "first interval"
220
tree[15:25] = "second interval"
221
tree[30:40] = "third interval"
222
223
print(f"Tree now contains {len(tree)} intervals")
224
225
# Equivalent to:
226
# tree.add(Interval(0, 10, "first interval"))
227
# tree.add(Interval(15, 25, "second interval"))
228
# tree.add(Interval(30, 40, "third interval"))
229
230
# Delete all intervals containing point 20
231
del tree[20] # Removes interval [15, 25)
232
print(f"After deletion: {len(tree)} intervals")
233
```
234
235
### Container Operations
236
237
```python
238
from intervaltree import Interval, IntervalTree
239
240
tree = IntervalTree([
241
Interval(0, 10, "a"),
242
Interval(15, 25, "b"),
243
Interval(30, 40, "c")
244
])
245
246
# Length
247
print(f"Tree contains {len(tree)} intervals")
248
249
# Membership testing
250
test_interval = Interval(15, 25, "b")
251
if test_interval in tree:
252
print("Interval found in tree")
253
254
# Test with different data (will not match)
255
test_interval2 = Interval(15, 25, "different")
256
if test_interval2 not in tree:
257
print("Interval with different data not found")
258
259
# Membership by values
260
if tree.containsi(0, 10, "a"):
261
print("Interval (0, 10, 'a') exists")
262
263
# Boolean evaluation (empty tree is falsy)
264
empty_tree = IntervalTree()
265
if not empty_tree:
266
print("Empty tree evaluates to False")
267
268
if tree:
269
print("Non-empty tree evaluates to True")
270
```
271
272
### Iteration Patterns
273
274
```python
275
from intervaltree import Interval, IntervalTree
276
277
tree = IntervalTree([
278
Interval(20, 30, "third"),
279
Interval(0, 10, "first"),
280
Interval(10, 20, "second")
281
])
282
283
# Basic iteration (automatically sorted)
284
print("All intervals:")
285
for interval in tree:
286
print(f" {interval}")
287
288
# Convert to list
289
interval_list = list(tree)
290
print(f"List of {len(interval_list)} intervals")
291
292
# Iterate with enumeration
293
print("Numbered intervals:")
294
for i, interval in enumerate(tree):
295
print(f" {i+1}: {interval}")
296
297
# Filter during iteration
298
print("Intervals with begin >= 10:")
299
for interval in tree:
300
if interval.begin >= 10:
301
print(f" {interval}")
302
303
# List comprehension
304
data_values = [interval.data for interval in tree]
305
print(f"Data values: {data_values}")
306
```
307
308
### Comparison and Equality
309
310
```python
311
from intervaltree import Interval, IntervalTree
312
313
# Create identical trees
314
tree1 = IntervalTree([
315
Interval(0, 10, "a"),
316
Interval(15, 25, "b")
317
])
318
319
tree2 = IntervalTree([
320
Interval(15, 25, "b"), # Order doesn't matter for equality
321
Interval(0, 10, "a")
322
])
323
324
tree3 = IntervalTree([
325
Interval(0, 10, "a"),
326
Interval(15, 25, "different") # Different data
327
])
328
329
# Equality testing
330
print(tree1 == tree2) # True - same intervals
331
print(tree1 == tree3) # False - different data in second interval
332
333
# Inequality
334
print(tree1 != tree3) # True
335
336
# Empty trees
337
empty1 = IntervalTree()
338
empty2 = IntervalTree()
339
print(empty1 == empty2) # True - both empty
340
```
341
342
### String Representation and Debugging
343
344
```python
345
from intervaltree import Interval, IntervalTree
346
347
tree = IntervalTree([
348
Interval(0, 10, "first"),
349
Interval(15, 25, "second")
350
])
351
352
# String representation
353
print(f"Tree: {tree}")
354
# Output: IntervalTree([Interval(0, 10, 'first'), Interval(15, 25, 'second')])
355
356
print(f"Repr: {repr(tree)}")
357
# Same as above
358
359
# Empty tree representation
360
empty = IntervalTree()
361
print(f"Empty tree: {empty}")
362
# Output: IntervalTree()
363
364
# Useful for debugging
365
print(f"Tree state: {tree}")
366
print(f"Tree length: {len(tree)}")
367
print(f"Tree empty: {len(tree) == 0}")
368
```
369
370
### Pickling and Serialization
371
372
```python
373
import pickle
374
from intervaltree import Interval, IntervalTree
375
376
# Create tree
377
tree = IntervalTree([
378
Interval(0, 10, "data1"),
379
Interval(15, 25, "data2")
380
])
381
382
# Serialize to bytes
383
pickled_data = pickle.dumps(tree)
384
print(f"Pickled size: {len(pickled_data)} bytes")
385
386
# Deserialize
387
restored_tree = pickle.loads(pickled_data)
388
print(f"Restored tree: {restored_tree}")
389
print(f"Trees equal: {tree == restored_tree}")
390
391
# File-based pickling
392
with open('/tmp/tree.pkl', 'wb') as f:
393
pickle.dump(tree, f)
394
395
with open('/tmp/tree.pkl', 'rb') as f:
396
loaded_tree = pickle.load(f)
397
398
print(f"Loaded from file: {loaded_tree == tree}")
399
```
400
401
### Advanced Python Integration
402
403
```python
404
from intervaltree import Interval, IntervalTree
405
406
# Create tree for advanced examples
407
tree = IntervalTree([
408
Interval(i, i+10, f"interval_{i}") for i in range(0, 100, 15)
409
])
410
411
# Use with built-in functions
412
print(f"Number of intervals: {len(tree)}")
413
print(f"Tree is empty: {not tree}")
414
415
# Sorting (already sorted, but demonstrates compatibility)
416
sorted_intervals = sorted(tree, key=lambda x: x.data)
417
418
# Filtering
419
long_intervals = [i for i in tree if i.length() > 5]
420
print(f"Long intervals: {len(long_intervals)}")
421
422
# Set operations (using standard Python set methods since IntervalTree is a MutableSet)
423
tree2 = IntervalTree([Interval(5, 15, "overlap")])
424
425
# MutableSet interface methods work
426
tree_copy = tree.copy()
427
tree_copy.discard(Interval(0, 10, "interval_0"))
428
429
# Use in set comprehensions
430
data_set = {interval.data for interval in tree}
431
print(f"Unique data values: {len(data_set)}")
432
433
# Compatible with any/all
434
has_long_intervals = any(i.length() > 20 for i in tree)
435
all_have_data = all(i.data is not None for i in tree)
436
print(f"Has long intervals: {has_long_intervals}")
437
print(f"All have data: {all_have_data}")
438
```