'Insert an element into a sorted list, and keep the list sorted.
The major difference from bisect.bisect_left is that this function supports a key method, so user doesn\'t have
to create the key array for each insertion.
:param list lst: The list. Must be pre-ordered.
:param object element: An element to insert into the list.
:param func key: A method to get the key for each element in the list.
:param int lo: Lower bound of the search.
:param int hi: Upper bound of the search.
:return: None'

@staticmethod
def _binary_insert(lst, elem, key, lo=0, hi=None):

    if (lo < 0):
        raise ValueError('lo    must    be    a    non-negative    number')
    if (hi is None):
        hi = len(lst)
    while (lo < hi):
        mid = ((lo + hi) // 2)
        if (key(lst[mid]) < key(elem)):
            lo = (mid + 1)
        else:
            hi = mid
    lst.insert(lo, elem)
