IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 二分查找 Python bisect 内置模块 -> 正文阅读

[Python知识库]二分查找 Python bisect 内置模块

第一部分 搞清 bisect 模块

★ 模块只针对 [升序列表]

i, j = 0, len(a) # ★[0, len(a)) 半开半闭区间
'''
bisect_left 左侧插入位置
'''
while i < j:
    mid = i + j >> 1    
    if a[mid] < target: i = mid + 1  # 递增 < i 三者关系,先判断小于
    else: j = mid 
return i
'''
bisect_right 右侧插入位置
'''
while i < j: 
    mid = i + j >> 1
    if a[mid] > target: j = mid # 先判断大于
    else: i = mid + 1
return i

实例

from bisect import *

a = [1, 2, 6, 6, 6, 8] # 升序
bisect_left(a, 4) # 插入位置 2, 对应元素 6 
bisect(a, 4)      # 同上
bisect_left(a, 6) # 同上
bisect(a, 6)      # 插入位置 5, 对应元素 8 

总结:

目标存在,左是最左 x;右是最右 x 的右邻居
目标不存在,左右相同,都是大于目标的元素位置。

  1. 注意是★插入位置
  2. 只针对★升序
  3. target 不存在,返回右邻居的位置;存在 bisect_left 返回第一个目标位置, bisect_right
    返回最后一个目标的右邻居的位置。
  4. 三者关系:bisect_left、<、i ;bisect_right、>、j
  5. 条件 while i < j: 返回 i = j

★35.搜索插入位置

★区分:插入位置与目标位置

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        return bisect_left(nums, target) 
        # 右查找在目标存在时与众不同,没有重复元素,右插入位置 - 1 = 左插入位置       
        i = bisect_right(nums, target)
        return i-1 if nums[i-1] == target else i

2089.找出数组排序后的目标下标

class Solution:
    def targetIndices(self, nums: List[int], target: int) -> List[int]:
        nums.sort()
        i = bisect_left(nums, target) 
        j = bisect_right(nums, target)
        return list(range(i, j))        

Python bisect 内置模块

文档
源代码: Lib/bisect.py
bisect,是实现 二分 (bisection) 算法 的模块,能够保持序列顺序不变的情况下对其进行 二分查找和插入

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

如果 x 已经在 a 里存在,那么插入点会在已存在元素之前(也就是左边)。

左半边 all(val < x for val in a[lo : i])
右半边 all(val >= x for val in a[i : hi])

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

返回的插入点是 a 中已存在元素 x 的右侧。

左半边 all(val <= x for val in a[lo : i])
右半边 all(val > x for val in a[i : hi])

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

按照已排序顺序将 x 插入到 a 中。

此函数首先会运行 bisect_left() 来定位一个插入点。 然后,它会在 a 上运行 insert() 方法在正确的位置插入 x 以保持排序顺序。

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

把 x 插入到 a 中已存在元素 x 的右侧。

在 a 上运行 insert() 方法在正确的位置插入 x 以保持排序顺序。

To support inserting records in a table, the key function (if any) is applied to x for the search step but not for the insertion step.

key specifies a 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.

If key is None, the elements are compared directly with no intervening function call.

二分法对于搜索一定范围的值是很高效的。 对于定位特定的值,则字典的性能更好。

注意,使用 bisect 模块的方法之前,要求操作对象是 有序序列(升、降)。
在序列 a 中二分查找适合元素 x 插入的位置,保证 a 仍为有序序列。
lo 和 hi 为可选参数,分别定义查找范围/返回索引的 上限和下限,缺省时默认对 整个 序列查找。
因此,返回的位置索引 又称为 “插入点”,将其设为 i,则序列 a 可以被划分为两部分,切片表示左侧 a[lo, i) 和右侧 a[i, hi] 。

Python bisect 源码

"""Bisection algorithms."""

def insort_right(a, x, lo=0, hi=None, *, key=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.
    """
    if key is None: lo = bisect_right(a, x, lo, hi)
    else: lo = bisect_right(a, key(x), lo, hi, key=key)
    a.insert(lo, x)


def bisect_right(a, x, lo=0, hi=None, *, key=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(i, 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)
    # Note, the comparison uses ">" to match the
    # __lt__() logic in list.sort() and in heapq.
    if key is None:
        while lo < hi:
            mid = (lo + hi) // 2
            if a[mid] > x: hi = mid
            else: lo = mid + 1
    else:
        while lo < hi:
            mid = (lo + hi) // 2
            if key(a[mid]) > x: hi = mid
            else: lo = mid + 1
    return lo


def insort_left(a, x, lo=0, hi=None, *, key=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.
    """

    if key is None: lo = bisect_left(a, x, lo, hi)
    else: lo = bisect_left(a, key(x), lo, hi, key=key)
    a.insert(lo, x)

def bisect_left(a, x, lo=0, hi=None, *, key=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(i, 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)
    # Note, the comparison uses "<" to match the
    # __lt__() logic in list.sort() and in heapq.
    if key is None:
        while lo < hi:
            mid = (lo + hi) // 2
            if a[mid] < x: lo = mid + 1
            else: hi = mid
    else:
        while lo < hi:
            mid = (lo + hi) // 2
            if key(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
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-06-26 16:52:04  更:2022-06-26 16:52:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 11:44:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码