from bisect import bisect_left, bisect_right
[docs]def index_of(_list: list, value):
"""Find index of element in given list."""
i = bisect_left(_list, value)
try:
assert value == _list[i], "Exact element not found."
return i
except (IndexError, AssertionError):
raise ValueError
[docs]def find_lt(_list: list, value):
"""Find rightmost value less than value."""
i = bisect_left(_list, value)
if i:
return _list[i-1]
raise ValueError
[docs]def find_lte(_list: list, value):
"""Find rightmost value less than or equal to value."""
i = bisect_right(_list, value)
if i:
return _list[i-1]
raise ValueError
[docs]def find_gt(_list: list, value):
"""Find leftmost value greater than value."""
i = bisect_right(_list, value)
if i != len(_list):
return _list[i]
raise ValueError
[docs]def find_gte(_list: list, value):
"""Find leftmost item greater than or equal to value."""
i = bisect_left(_list, value)
if i != len(_list):
return _list[i]
raise ValueError
[docs]def find_delimiters(_list: list, first_element, second_element) -> tuple:
"""
Given a list of elements, searches:
* the index of the first element included in the given range
* the index of the last element included in the given range
Args:
_list (list): Input data.
first_element: Low limit of the range to search.
second_element: High limit of the range to search.
Returns:
tuple: First and last indexes of the searched range.
"""
idx_min = bisect_left(_list, first_element)
idx_max = bisect_right(_list[idx_min:], second_element) + idx_min - 1
return idx_min, idx_max