def __ior__(self, other): """ Replace the segmentlist with the union of itself and another. If the two lists have numbers of elements n and m respectively, then for m << n the algorithm is O(m log n), otherwise it is O((n + m) log (n + m)). """ if len(other) > len(self) / 2: self.extend(other) return self.coalesce() if other is self: return self i = 0 for seg in other: i = j = _bisect_right(self, seg, i) lo, hi = seg if i and self[i - 1][1] >= lo: i -= 1 lo = self[i][0] n = len(self) while j < n and self[j][0] <= hi: j += 1 if j > i: self[i] = segment(lo, max(hi, self[j - 1][1])) del self[i + 1:j] else: self.insert(i, seg) i += 1 return self
def __ior__(self, other): """ Replace the segmentlist with the union of itself and another. If the two lists have numbers of elements n and m respectively, then for m << n the algorithm is O(m log n), otherwise it is O((n + m) log (n + m)). """ if len(other) > len(self) / 2: self.extend(other) return self.coalesce() if other is self: return self i = 0 for seg in other: i = j = _bisect_right(self, seg, i) lo, hi = seg if i and self[i - 1][1] >= lo: i -= 1 lo = self[i][0] n = len(self) while j < n and self[j][0] <= hi: j += 1 if j > i: self[i] = segment(lo, max(hi, self[j - 1][1])) del self[i + 1 : j] else: self.insert(i, seg) i += 1 return self
def _check_param(name, param, grid): if param < grid[0]: raise ValueError(f'{name} too small: {param}') elif param < grid[-1]: idx = _bisect_right(grid, param) - 1 elif param == grid[-1]: idx = len(grid) - 2 else: raise ValueError(f'{name} too big: {param}') return idx
def __setitem__(self, index, item): """this does not support item assignment""" raise TypeError( f"{type(self).__name__!r} object does not support item assignment") k = self._key(item) i = _bisect_left(self._keys, k) j = _bisect_right(self._keys, k) print(f"{item=} {index=} {i=} {j=}") if (i == j) and i == index: self._keys[i] = k self._items[i] = item else: raise ValueError( "Can't insert item in position {index} and preserve the order")
def get_index(values, value): return _bisect_right(values, value) - 1
def insert_right(self, item): 'Insert a new item. If equal keys are found, add to the right' k = self._key(item) i = _bisect_right(self._keys, k) self._keys.insert(i, k) self._items.insert(i, item)
def __contains__(self, item): k = self._key(item) lo = _bisect_left(self._keys, k) hi = _bisect_right(self._keys, k) items = self._items return any(item == items[i] for i in range(lo, hi))