8.5. bisect — Array bisection algorithm

python标准库
8 数据类型

目标:使用一个基础的二分查找算法维护一个有序List。

可使用函数:

  1. bisect.bisect_left(a, x, lo=0, hi=len(a))
    a是有序List,返回的索引是第一个等于x的第一个或大于x的第一个索引。lo和hi是取出a中的一部分。
    返回的索引i满足 左边 all(val < x for val in a[lo:i])
    右边 all(val >= x for val in a[i:hi])

  2. bisect.bisect_right(a, x, lo=0, hi=len(a))
    bisect.bisect(a, x, lo=0, hi=len(a))
    a是有序List,返回的索引是大于x的第一个索引。lo和hi是取出a中的一部分。
    返回的索引i满足 左边 all(val <= x for val in a[lo:i])
    右边 all(val > x for val in a[i:hi])

  3. bisect.insort_left(a, x, lo=0, hi=len(a))
    等价于 a.insert(bisect.bisect_left(a, x, lo, hi), x)

  4. bisect.insort_right(a, x, lo=0, hi=len(a))
    bisect.insort(a, x, lo=0, hi=len(a))
    等价于 a.insert(bisect.bisect_right(a, x, lo, hi), x)

举例:

def index(a, x):
    # 定位最左边的x'
    i = bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    raise ValueError

def find_lt(a, x):
    'val<x的集合'
    i = bisect_left(a, x)
    if i:
        return a[:i-1]
    raise ValueError

def find_le(a, x):
    'val<= x的集合'
    i = bisect_right(a, x)
    if i:
        return a[:i-1]
    raise ValueError

def find_gt(a, x):
    ' val > x的集合
    i = bisect_right(a, x)
    if i != len(a):
        return a[i:]
    raise ValueError

def find_ge(a, x):
    # val >= x的集合
    i = bisect_left(a, x)
    if i != len(a):
        return a[i:]
    raise ValueError
# 分数排名,0-59:F,60-69:D , 70-79:C  ,   80-89:B  ,  90-> A
>>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
        i = bisect(breakpoints, score)
        return grades[i]
# 返回score在breakpoints的右索引,始终是>score的。
>>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
#对于70,77返回的都是2-C;对于90,99,100,返回的都是4-A;对于小于60的始终取A
['F', 'A', 'C', 'C', 'B', 'A', 'A']

函数解析

def bisect_left(a, x, lo=0, hi=None):
    """a是有序List,返回的索引是第一个等于x的第一个或大于x的第一个索引。
       lo和hi是取出a中的一部分。
	   返回的索引i满足 左边 all(val < x for val in a[lo:i])
	   右边 all(val >= x for val in a[i:hi])
    """
    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      
        #相等时让hi降下来                                                
        else: hi = mid
    return lo
def bisect_right(a, x, lo=0, hi=None):
    """a是有序List,返回的索引是第一个大于x的第一个索引。
       lo和hi是取出a中的一部分。
	   返回的索引i满足 左边 all(val <= x for val in a[lo:i])
	   右边 all(val > x for val in a[i:hi])
    """

    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
        # 相等时让lo升下来    
        else: lo = mid+1
    return lo
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值