bisect.py 2.53 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.
    """

Georg Brandl's avatar
Georg Brandl committed
12 13
    if lo < 0:
        raise ValueError('lo must be non-negative')
14 15 16
    if hi is None:
        hi = len(a)
    while lo < hi:
17
        mid = (lo+hi)//2
18 19 20
        if x < a[mid]: hi = mid
        else: lo = mid+1
    a.insert(lo, x)
21

22 23 24 25 26 27
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
28 29
    a[i:] have e > x.  So if x already appears in the list, a.insert(x) will
    insert just after the rightmost x already there.
30 31 32 33

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

Georg Brandl's avatar
Georg Brandl committed
35 36
    if lo < 0:
        raise ValueError('lo must be non-negative')
37 38 39
    if hi is None:
        hi = len(a)
    while lo < hi:
40
        mid = (lo+hi)//2
41 42 43
        if x < a[mid]: hi = mid
        else: lo = mid+1
    return lo
44 45 46 47 48 49 50 51 52 53 54 55

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.
    """

Georg Brandl's avatar
Georg Brandl committed
56 57
    if lo < 0:
        raise ValueError('lo must be non-negative')
58 59 60
    if hi is None:
        hi = len(a)
    while lo < hi:
61
        mid = (lo+hi)//2
62 63 64 65 66 67 68 69 70
        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
71 72
    a[i:] have e >= x.  So if x already appears in the list, a.insert(x) will
    insert just before the leftmost x already there.
73 74 75 76 77

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

Georg Brandl's avatar
Georg Brandl committed
78 79
    if lo < 0:
        raise ValueError('lo must be non-negative')
80 81 82
    if hi is None:
        hi = len(a)
    while lo < hi:
83
        mid = (lo+hi)//2
84 85 86
        if a[mid] < x: lo = mid+1
        else: hi = mid
    return lo
87 88 89

# Overwrite above definitions with a fast C implementation
try:
90
    from _bisect import *
91 92
except ImportError:
    pass