bisect
— algorytm bisekcji tablicy¶
Source code: Lib/bisect.py
Ten moduł dostarcza wsparcia dla utrzymywania listy w posortowanym porządku bez konieczności sortowania listy po każdym wstawieniu. Dla długich list elementów o kosztownych operacjach porównania, to może być polepszenie względem bardziej typowego podejścia. Moduł jest zwany bisect
ponieważ używa używa podstawowego algorytmu bisekcji aby wykonać swoją pracę. Kod źródłowy może być najbardziej użyteczny jako działający przykład algorytmu (warunki brzegowe są już od razu poprawne!).
Następujące zadania są dostarczone:
-
bisect.
bisect_left
(a, x, lo=0, hi=len(a))¶ Locate the insertion point for x in a to maintain sorted order. The parameters lo and hi may be used to specify a subset of the list which should be considered; by default the entire list is used. If x is already present in a, the insertion point will be before (to the left of) any existing entries. The return value is suitable for use as the first parameter to
list.insert()
assuming that a is already sorted.The returned insertion point i partitions the array a into two halves so that
all(val < x for val in a[lo:i])
for the left side andall(val >= x for val in a[i:hi])
for the right side.
-
bisect.
bisect_right
(a, x, lo=0, hi=len(a))¶ -
bisect.
bisect
(a, x, lo=0, hi=len(a))¶ Podobna do funkcji
bisect_left()
ale zwraca punkt wstawiania który jest po (po prawej stronie od) jakichkolwiek wpisów x w a.The returned insertion point i partitions the array a into two halves so that
all(val <= x for val in a[lo:i])
for the left side andall(val > x for val in a[i:hi])
for the right side.
-
bisect.
insort_left
(a, x, lo=0, hi=len(a))¶ Insert x in a in sorted order. This is equivalent to
a.insert(bisect.bisect_left(a, x, lo, hi), x)
assuming that a is already sorted. Keep in mind that the O(log n) search is dominated by the slow O(n) insertion step.
-
bisect.
insort_right
(a, x, lo=0, hi=len(a))¶ -
bisect.
insort
(a, x, lo=0, hi=len(a))¶ Podobna do funkcji
insort_left()
, ale wstawiając x w a po jakichkolwiek wpisach x.
Zobacz także
SortedCollection recipe that uses bisect to build a full-featured collection class with straight-forward search methods and support for a key-function. The keys are precomputed to save unnecessary calls to the key function during searches.
Searching Sorted Lists¶
The above bisect()
functions are useful for finding insertion points but
can be tricky or awkward to use for common searching tasks. The following five
functions show how to transform them into the standard lookups for sorted
lists:
def index(a, x):
'Locate the leftmost value exactly equal to x'
i = bisect_left(a, x)
if i != len(a) and a[i] == x:
return i
raise ValueError
def find_lt(a, x):
'Find rightmost value less than x'
i = bisect_left(a, x)
if i:
return a[i-1]
raise ValueError
def find_le(a, x):
'Find rightmost value less than or equal to x'
i = bisect_right(a, x)
if i:
return a[i-1]
raise ValueError
def find_gt(a, x):
'Find leftmost value greater than x'
i = bisect_right(a, x)
if i != len(a):
return a[i]
raise ValueError
def find_ge(a, x):
'Find leftmost item greater than or equal to x'
i = bisect_left(a, x)
if i != len(a):
return a[i]
raise ValueError
Other Examples¶
The bisect()
function can be useful for numeric table lookups. This
example uses bisect()
to look up a letter grade for an exam score (say)
based on a set of ordered numeric breakpoints: 90 and up is an «A», 80 to 89 is
a «B», and so on:
>>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
... i = bisect(breakpoints, score)
... return grades[i]
...
>>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
Unlike the sorted()
function, it does not make sense for the bisect()
functions to have key or reversed arguments because that would lead to an
inefficient design (successive calls to bisect functions would not „remember”
all of the previous key lookups).
Zamiast tego, lepiej jest przeszukać listę uprzednio obliczonych wartości kluczowych aby odnaleźć indeks poszukiwanego zapisu:
>>> data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
>>> data.sort(key=lambda r: r[1])
>>> keys = [r[1] for r in data] # precomputed list of keys
>>> data[bisect_left(keys, 0)]
('black', 0)
>>> data[bisect_left(keys, 1)]
('blue', 1)
>>> data[bisect_left(keys, 5)]
('red', 5)
>>> data[bisect_left(keys, 8)]
('yellow', 8)