【Python】 基于二分的查找和插入模块 bisect (示例+源码)

模块名

bisect

使用这个模块的函数前,需要先确保操作的列表是已排序的。


查找函数

二分查找将 item 插入 list 时,插入位置的下标。并不实际执行插入操作。

bisect_left(list, item) :如果 list 中存在 item ,则返回插入到这些 item 左侧 后的的下标。

bisect(list, item)bisect_right(list, item) :如果 list 中存在 item ,则返回插入到这些 item 右侧 后的的下标。


插入函数

通过二分查找查找插入位置,并执行插入操作,使得操作后的列表保持有序。

insort_left(list, item) :如果 list 中存在 item ,则插入到这些 item左侧

insort(list, item)insort_right(list, item) :如果 list 中存在 item ,则插入到这些 item右侧


代码示例

from bisect import *

l = [3, 6, 8, 8, 10]

# 查找
bisect_left(l, 1)		# 返回值:0
bisect_left(l, 7)		# 返回值:2
bisect_left(l, 8)		# 返回值:2
bisect_left(l, 15)		# 返回值:5

bisect_right(l, 1)		# 返回值:0
bisect_right(l, 7)		# 返回值:2
bisect_right(l, 8)		# 返回值:4
bisect_right(l, 15)		# 返回值:5

# 插入
l = [6, 8, 8, 10]
insort_left(l, 1)		# l = [1, 6, 8, 8, 10]
insort_left(l, 7)		# l = [1, 6, 7, 8, 8, 10]
insort_left(l, 8.0)		# l = [1, 6, 7, 8.0, 8, 8, 10]
insort_left(l, 15)		# l = [1, 6, 7, 8.0, 8, 8, 10, 15]

l = [6, 8, 8, 10]
insort_right(l, 1)		# l = [1, 6, 8, 8, 10]
insort_right(l, 7)		# l = [1, 6, 7, 8, 8, 10]
insort_right(l, 8.0)	# l = [1, 6, 7, 8, 8, 8.0, 10]
insort_right(l, 15)		# l = [1, 6, 7, 8, 8, 8.0, 10, 15]

模块源码

"""Bisection algorithms."""

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

    lo = bisect_right(a, x, lo, hi)
    a.insert(lo, x)

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, a.insert(x) will
    insert just after the rightmost x already there.

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

    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if x < a[mid]: hi = mid
        else: lo = mid+1
    return lo

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

    lo = bisect_left(a, x, lo, hi)
    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, a.insert(x) will
    insert 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 lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if a[mid] < x: lo = mid+1
        else: hi = mid
    return lo

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

# Create aliases
bisect = bisect_right
insort = insort_right
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值