Hướng dẫn python sorted list bisect_left - danh sách được sắp xếp trong python bisect_left

Mã nguồn: lib/bisect.py Lib/bisect.py


Mô -đun này cung cấp hỗ trợ để duy trì danh sách theo thứ tự được sắp xếp mà không phải sắp xếp danh sách sau mỗi lần chèn. Đối với danh sách dài các mục có hoạt động so sánh đắt tiền, đây có thể là một cải tiến so với cách tiếp cận phổ biến hơn. Mô -đun được gọi là bisect vì nó sử dụng thuật toán chia đôi cơ bản để thực hiện công việc của nó. Mã nguồn có thể hữu ích nhất như một ví dụ hoạt động của thuật toán (các điều kiện biên đã đúng!).

Các chức năng sau được cung cấp:

bisect.bisect_left (a, x, lo = 0, hi = len (a), *, key = none) ¶bisect_left(a, x, lo=0, hi=len(a), *, key=None)

Xác định vị trí điểm chèn cho X trong A để duy trì thứ tự được sắp xếp. Các tham số LO và HI có thể được sử dụng để chỉ định một tập hợp con của danh sách cần được xem xét; Theo mặc định, toàn bộ danh sách được sử dụng. Nếu X đã có mặt trong A, điểm chèn sẽ ở trước (bên trái) mọi mục hiện có. Giá trị trả về phù hợp để sử dụng làm tham số đầu tiên cho list.insert() giả sử rằng A đã được sắp xếp.

Điểm chèn trả về I phân vùng mảng A thành hai nửa sao cho all(val < x for val in a[lo : i]) cho bên trái và all(val >= x for val in a[i : hi]) cho phía bên phải.

Khóa chỉ định chức năng chính của một đối số được sử dụng để trích xuất một khóa so sánh từ mỗi phần tử trong mảng. Để hỗ trợ tìm kiếm các bản ghi phức tạp, chức năng chính không được áp dụng cho giá trị x.key function of one argument that is used to extract a comparison key from each element in the array. To support searching complex records, the key function is not applied to the x value.

Nếu khóa là None, các phần tử được so sánh trực tiếp mà không có cuộc gọi chức năng can thiệp.

Đã thay đổi trong phiên bản 3.10: Đã thêm tham số chính.Added the key parameter.

bisect.bisect_right (a, x, lo = 0, hi = len (a), *, key = none) ¶ bisect.bisect (a, x, lo = 0, hi = len ) ¶bisect_right(a, x, lo=0, hi=len(a), *, key=None)bisect.bisect(a, x, lo=0, hi=len(a), *, key=None)

Tương tự như bisect_left(), nhưng trả về một điểm chèn xuất hiện sau (bên phải) bất kỳ mục nào hiện có của X trong a.

Điểm chèn trả về I phân vùng mảng A thành hai nửa sao cho

>>> 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']
0 cho bên trái và
>>> 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']
1 cho phía bên phải.

Khóa chỉ định chức năng chính của một đối số được sử dụng để trích xuất một khóa so sánh từ mỗi phần tử trong mảng. Để hỗ trợ tìm kiếm các bản ghi phức tạp, chức năng chính không được áp dụng cho giá trị x.key function of one argument that is used to extract a comparison key from each element in the array. To support searching complex records, the key function is not applied to the x value.

Nếu khóa là None, các phần tử được so sánh trực tiếp mà không có cuộc gọi chức năng can thiệp.

Đã thay đổi trong phiên bản 3.10: Đã thêm tham số chính.Added the key parameter.

bisect.bisect_right (a, x, lo = 0, hi = len (a), *, key = none) ¶ bisect.bisect (a, x, lo = 0, hi = len ) ¶insort_left(a, x, lo=0, hi=len(a), *, key=None)

Tương tự như bisect_left(), nhưng trả về một điểm chèn xuất hiện sau (bên phải) bất kỳ mục nào hiện có của X trong a.

Điểm chèn trả về I phân vùng mảng A thành hai nửa sao cho

>>> 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']
0 cho bên trái và
>>> 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']
1 cho phía bên phải.

bisect.insort_left (a, x, lo = 0, hi = len (a), *, key = none) ¶

Chèn x theo thứ tự sắp xếp.

Đã thay đổi trong phiên bản 3.10: Đã thêm tham số chính.Added the key parameter.

bisect.bisect_right (a, x, lo = 0, hi = len (a), *, key = none) ¶ bisect.bisect (a, x, lo = 0, hi = len ) ¶insort_right(a, x, lo=0, hi=len(a), *, key=None)bisect.insort(a, x, lo=0, hi=len(a), *, key=None)

Tương tự như bisect_left(), nhưng trả về một điểm chèn xuất hiện sau (bên phải) bất kỳ mục nào hiện có của X trong a.

Điểm chèn trả về I phân vùng mảng A thành hai nửa sao cho

>>> 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']
0 cho bên trái và
>>> 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']
1 cho phía bên phải.

bisect.insort_left (a, x, lo = 0, hi = len (a), *, key = none) ¶

Chèn x theo thứ tự sắp xếp.

Đã thay đổi trong phiên bản 3.10: Đã thêm tham số chính.Added the key parameter.

bisect.bisect_right (a, x, lo = 0, hi = len (a), *, key = none) ¶ bisect.bisect (a, x, lo = 0, hi = len ) ¶

Tương tự như bisect_left(), nhưng trả về một điểm chèn xuất hiện sau (bên phải) bất kỳ mục nào hiện có của X trong a.

  • Điểm chèn trả về I phân vùng mảng A thành hai nửa sao cho

    >>> 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']
    
    0 cho bên trái và
    >>> 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']
    
    1 cho phía bên phải.

  • bisect.insort_left (a, x, lo = 0, hi = len (a), *, key = none) ¶

  • Chèn x theo thứ tự sắp xếp.

Hàm này đầu tiên chạy bisect_left() để xác định vị trí điểm chèn. Tiếp theo, nó chạy phương thức

>>> 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']
4 trên A để chèn x ở vị trí thích hợp để duy trì thứ tự sắp xếp.

  • Để hỗ trợ chèn các bản ghi vào bảng, hàm chính (nếu có) được áp dụng cho X cho bước tìm kiếm nhưng không phải cho bước chèn.

  • Hãy nhớ rằng tìm kiếm

    >>> 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']
    
    5 bị chi phối bởi bước chèn O (N) chậm.

bisect.insort_right (a, x, lo = 0, hi = len (a), *, key = none) ) ¶

Tương tự như

>>> 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']
6, nhưng chèn X vào A sau bất kỳ mục nào hiện có của X.

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

Ví dụ;

Hàm

>>> from collections import namedtuple
>>> from operator import attrgetter
>>> from bisect import bisect, insort
>>> from pprint import pprint

>>> Movie = namedtuple('Movie', ('name', 'released', 'director'))

>>> movies = [
...     Movie('Jaws', 1975, 'Speilberg'),
...     Movie('Titanic', 1997, 'Cameron'),
...     Movie('The Birds', 1963, 'Hitchcock'),
...     Movie('Aliens', 1986, 'Scott')
... ]

>>> # Find the first movie released after 1960
>>> by_year = attrgetter('released')
>>> movies.sort(key=by_year)
>>> movies[bisect(movies, 1960, key=by_year)]
Movie(name='The Birds', released=1963, director='Hitchcock')

>>> # Insert a movie while maintaining sort order
>>> romance = Movie('Love Story', 1970, 'Hiller')
>>> insort(movies, romance, key=by_year)
>>> pprint(movies)
[Movie(name='The Birds', released=1963, director='Hitchcock'),
 Movie(name='Love Story', released=1970, director='Hiller'),
 Movie(name='Jaws', released=1975, director='Speilberg'),
 Movie(name='Aliens', released=1986, director='Scott'),
 Movie(name='Titanic', released=1997, director='Cameron')]
2 có thể hữu ích cho việc tra cứu bảng số.Ví dụ này sử dụng
>>> from collections import namedtuple
>>> from operator import attrgetter
>>> from bisect import bisect, insort
>>> from pprint import pprint

>>> Movie = namedtuple('Movie', ('name', 'released', 'director'))

>>> movies = [
...     Movie('Jaws', 1975, 'Speilberg'),
...     Movie('Titanic', 1997, 'Cameron'),
...     Movie('The Birds', 1963, 'Hitchcock'),
...     Movie('Aliens', 1986, 'Scott')
... ]

>>> # Find the first movie released after 1960
>>> by_year = attrgetter('released')
>>> movies.sort(key=by_year)
>>> movies[bisect(movies, 1960, key=by_year)]
Movie(name='The Birds', released=1963, director='Hitchcock')

>>> # Insert a movie while maintaining sort order
>>> romance = Movie('Love Story', 1970, 'Hiller')
>>> insort(movies, romance, key=by_year)
>>> pprint(movies)
[Movie(name='The Birds', released=1963, director='Hitchcock'),
 Movie(name='Love Story', released=1970, director='Hiller'),
 Movie(name='Jaws', released=1975, director='Speilberg'),
 Movie(name='Aliens', released=1986, director='Scott'),
 Movie(name='Titanic', released=1997, director='Cameron')]
2 để tìm kiếm một lớp thư cho điểm thi (giả sử) dựa trên một tập hợp các điểm dừng số được đặt hàng: 90 trở lên là một ’A, 80 đến 89 là một’ b, v.v.

>>> 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']

Các hàm

>>> from collections import namedtuple
>>> from operator import attrgetter
>>> from bisect import bisect, insort
>>> from pprint import pprint

>>> Movie = namedtuple('Movie', ('name', 'released', 'director'))

>>> movies = [
...     Movie('Jaws', 1975, 'Speilberg'),
...     Movie('Titanic', 1997, 'Cameron'),
...     Movie('The Birds', 1963, 'Hitchcock'),
...     Movie('Aliens', 1986, 'Scott')
... ]

>>> # Find the first movie released after 1960
>>> by_year = attrgetter('released')
>>> movies.sort(key=by_year)
>>> movies[bisect(movies, 1960, key=by_year)]
Movie(name='The Birds', released=1963, director='Hitchcock')

>>> # Insert a movie while maintaining sort order
>>> romance = Movie('Love Story', 1970, 'Hiller')
>>> insort(movies, romance, key=by_year)
>>> pprint(movies)
[Movie(name='The Birds', released=1963, director='Hitchcock'),
 Movie(name='Love Story', released=1970, director='Hiller'),
 Movie(name='Jaws', released=1975, director='Speilberg'),
 Movie(name='Aliens', released=1986, director='Scott'),
 Movie(name='Titanic', released=1997, director='Cameron')]
2 và
>>> from collections import namedtuple
>>> from operator import attrgetter
>>> from bisect import bisect, insort
>>> from pprint import pprint

>>> Movie = namedtuple('Movie', ('name', 'released', 'director'))

>>> movies = [
...     Movie('Jaws', 1975, 'Speilberg'),
...     Movie('Titanic', 1997, 'Cameron'),
...     Movie('The Birds', 1963, 'Hitchcock'),
...     Movie('Aliens', 1986, 'Scott')
... ]

>>> # Find the first movie released after 1960
>>> by_year = attrgetter('released')
>>> movies.sort(key=by_year)
>>> movies[bisect(movies, 1960, key=by_year)]
Movie(name='The Birds', released=1963, director='Hitchcock')

>>> # Insert a movie while maintaining sort order
>>> romance = Movie('Love Story', 1970, 'Hiller')
>>> insort(movies, romance, key=by_year)
>>> pprint(movies)
[Movie(name='The Birds', released=1963, director='Hitchcock'),
 Movie(name='Love Story', released=1970, director='Hiller'),
 Movie(name='Jaws', released=1975, director='Speilberg'),
 Movie(name='Aliens', released=1986, director='Scott'),
 Movie(name='Titanic', released=1997, director='Cameron')]
6 cũng hoạt động với danh sách các bộ dữ liệu.Đối số chính có thể phục vụ để trích xuất trường được sử dụng để đặt hàng trong bảng:

>>> from collections import namedtuple
>>> from operator import attrgetter
>>> from bisect import bisect, insort
>>> from pprint import pprint

>>> Movie = namedtuple('Movie', ('name', 'released', 'director'))

>>> movies = [
...     Movie('Jaws', 1975, 'Speilberg'),
...     Movie('Titanic', 1997, 'Cameron'),
...     Movie('The Birds', 1963, 'Hitchcock'),
...     Movie('Aliens', 1986, 'Scott')
... ]

>>> # Find the first movie released after 1960
>>> by_year = attrgetter('released')
>>> movies.sort(key=by_year)
>>> movies[bisect(movies, 1960, key=by_year)]
Movie(name='The Birds', released=1963, director='Hitchcock')

>>> # Insert a movie while maintaining sort order
>>> romance = Movie('Love Story', 1970, 'Hiller')
>>> insort(movies, romance, key=by_year)
>>> pprint(movies)
[Movie(name='The Birds', released=1963, director='Hitchcock'),
 Movie(name='Love Story', released=1970, director='Hiller'),
 Movie(name='Jaws', released=1975, director='Speilberg'),
 Movie(name='Aliens', released=1986, director='Scott'),
 Movie(name='Titanic', released=1997, director='Cameron')]

Nếu chức năng chính là tốn kém, có thể tránh các cuộc gọi chức năng lặp đi lặp lại bằng cách tìm kiếm một danh sách các khóa được tính toán trước để tìm chỉ mục của bản ghi:

>>> data = [('red', 5), ('blue', 1), ('yellow', 8), ('black', 0)]
>>> data.sort(key=lambda r: r[1])       # Or use operator.itemgetter(1).
>>> keys = [r[1] for r in data]         # Precompute a 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)