bisect.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. """Bisection algorithms."""
  2. def insort_right(a, x, lo=0, hi=None):
  3. """Insert item x in list a, and keep it sorted assuming a is sorted.
  4. If x is already in a, insert it to the right of the rightmost x.
  5. Optional args lo (default 0) and hi (default len(a)) bound the
  6. slice of a to be searched.
  7. """
  8. lo = bisect_right(a, x, lo, hi)
  9. a.insert(lo, x)
  10. def bisect_right(a, x, lo=0, hi=None):
  11. """Return the index where to insert item x in list a, assuming a is sorted.
  12. The return value i is such that all e in a[:i] have e <= x, and all e in
  13. a[i:] have e > x. So if x already appears in the list, a.insert(x) will
  14. insert just after the rightmost x already there.
  15. Optional args lo (default 0) and hi (default len(a)) bound the
  16. slice of a to be searched.
  17. """
  18. if lo < 0:
  19. raise ValueError('lo must be non-negative')
  20. if hi is None:
  21. hi = len(a)
  22. while lo < hi:
  23. mid = (lo+hi)//2
  24. # Use __lt__ to match the logic in list.sort() and in heapq
  25. if x < a[mid]: hi = mid
  26. else: lo = mid+1
  27. return lo
  28. def insort_left(a, x, lo=0, hi=None):
  29. """Insert item x in list a, and keep it sorted assuming a is sorted.
  30. If x is already in a, insert it to the left of the leftmost x.
  31. Optional args lo (default 0) and hi (default len(a)) bound the
  32. slice of a to be searched.
  33. """
  34. lo = bisect_left(a, x, lo, hi)
  35. a.insert(lo, x)
  36. def bisect_left(a, x, lo=0, hi=None):
  37. """Return the index where to insert item x in list a, assuming a is sorted.
  38. The return value i is such that all e in a[:i] have e < x, and all e in
  39. a[i:] have e >= x. So if x already appears in the list, a.insert(x) will
  40. insert just before the leftmost x already there.
  41. Optional args lo (default 0) and hi (default len(a)) bound the
  42. slice of a to be searched.
  43. """
  44. if lo < 0:
  45. raise ValueError('lo must be non-negative')
  46. if hi is None:
  47. hi = len(a)
  48. while lo < hi:
  49. mid = (lo+hi)//2
  50. # Use __lt__ to match the logic in list.sort() and in heapq
  51. if a[mid] < x: lo = mid+1
  52. else: hi = mid
  53. return lo
  54. # Overwrite above definitions with a fast C implementation
  55. try:
  56. from _bisect import *
  57. except ImportError:
  58. pass
  59. # Create aliases
  60. bisect = bisect_right
  61. insort = insort_right