This is the answer for the simple range with step=1 case (99% of the time), which can be 2500x faster as shown in the benchmark when comparing long ranges using sets (when you are just interested in knowing if there is overlap):
x = range(1,10)
y = range(8,20)
def range_overlapping(x, y):
if x.start == x.stop or y.start == y.stop:
return False
return x.start <= y.stop and y.start <= x.stop
>>> range_overlapping(x, y)
True
To find the overlapping values:
def overlap(x, y):
if not range_overlapping(x, y):
return set()
return set(range(max(x.start, y.start), min(x.stop, y.stop)+1))
Visual help:
| | | |
| | | |
Benchmark:
x = range(1,10)
y = range(8,20)
In [151]: %timeit set(x).intersection(y)
2.74 µs ± 11.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [152]: %timeit range_overlapping(x, y)
1.4 µs ± 2.91 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Conclusion: even for small ranges, it is twice as fast.
x = range(1,10000)
y = range(50000, 500000)
In [155]: %timeit set(x).intersection(y)
43.1 ms ± 158 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [156]: %timeit range_overlapping(x, y)
1.75 µs ± 88.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Conclusion: you want to use the range_overlapping function in this case as it is 2500x faster (my personal record in speedup)