bisect.py 2.13 KB
Newer Older
1
"""Bisection algorithms."""
2

3 4 5 6 7 8 9 10 11
def insort_right(a, x, lo=0, hi=None):
    """Insert item x in list a, and keep it sorted assuming a is sorted.

    If x is already in a, insert it to the right of the rightmost x.

    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """

12 13 14
    if hi is None:
        hi = len(a)
    while lo < hi:
15
        mid = (lo+hi)//2
16 17 18
        if x < a[mid]: hi = mid
        else: lo = mid+1
    a.insert(lo, x)
19

20 21 22 23 24 25 26 27 28 29 30 31
insort = insort_right   # backward compatibility

def bisect_right(a, x, lo=0, hi=None):
    """Return the index where to insert item x in list a, assuming a is sorted.

    The return value i is such that all e in a[:i] have e <= x, and all e in
    a[i:] have e > x.  So if x already appears in the list, i points just
    beyond the rightmost x already there.

    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """
32

33 34 35
    if hi is None:
        hi = len(a)
    while lo < hi:
36
        mid = (lo+hi)//2
37 38 39
        if x < a[mid]: hi = mid
        else: lo = mid+1
    return lo
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

bisect = bisect_right   # backward compatibility

def insort_left(a, x, lo=0, hi=None):
    """Insert item x in list a, and keep it sorted assuming a is sorted.

    If x is already in a, insert it to the left of the leftmost x.

    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """

    if hi is None:
        hi = len(a)
    while lo < hi:
55
        mid = (lo+hi)//2
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
        if a[mid] < x: lo = mid+1
        else: hi = mid
    a.insert(lo, x)


def bisect_left(a, x, lo=0, hi=None):
    """Return the index where to insert item x in list a, assuming a is sorted.

    The return value i is such that all e in a[:i] have e < x, and all e in
    a[i:] have e >= x.  So if x already appears in the list, i points just
    before the leftmost x already there.

    Optional args lo (default 0) and hi (default len(a)) bound the
    slice of a to be searched.
    """

    if hi is None:
        hi = len(a)
    while lo < hi:
75
        mid = (lo+hi)//2
76 77 78
        if a[mid] < x: lo = mid+1
        else: hi = mid
    return lo