Python中bisect的使用方法


Posted in Python onDecember 31, 2019

Python中列表(list)的实现其实是一个数组,当要查找某一个元素的时候时间复杂度是O(n),使用list.index()方法,但是随着数据量的上升,list.index()的性能也逐步下降,所以我们需要使用bisect模块来进行二分查找,前提我们的列表是一个有序的列表。

递归二分查找和循环二分查找

def binary_search_recursion(lst, val, start, end):
  if start > end:
    return None
  mid = (start + end) // 2
  if lst[mid] < val:
    return binary_search_recursion(lst, val, mid + 1, end)
  if lst[mid] > val:
    return binary_search_recursion(lst, val, start, mid - 1)
  return mid
 
 
def binary_search_loop(lst, val):
  start, end = 0, len(lst) - 1
  while start <= end:
    mid = (start + end) // 2
    if lst[mid] < val:
      start = mid + 1
    elif lst[mid] > val:
      end = mid - 1
    else:
      return mid
  return None

为了比对一下两者的性能,我们使用timeit模块来测试两个方法执行,timeit模块的timeit方法默认会对需要测试的函数执行1000000,然后返回执行的时间。

>>> import random
>>> from random import randint
>>> from random import choice
>>> random.seed(5)
>>> lst = [randint(1, 100) for _ in range(500000)]
>>> lst.sort()
>>> val = choice(lst)
>>> val
6
>>> def test_recursion():
...   return binary_search_recursion(lst, val, 0, len(lst) - 1)
...
>>> def test_loop():
...   return binary_search_loop(lst, val)
...
>>> import timeit
>>> t1 = timeit.timeit("test_recursion()", setup="from __main__ import test_recursion")
>>> t1
3.9838006450511045
>>> t2 = timeit.timeit("test_loop()", setup="from __main__ import test_loop")
>>> t2
2.749765167240339

可以看到,循环二分查找比递归二分查找性能要来的好些。现在,我们先用bisect的二分查找测试一下性能

用bisect来搜索

>>> import bisect
>>> def binary_search_bisect(lst, val):
...   i = bisect.bisect(lst, val)
...   if i != len(lst) and lst[i] == val:
...     return i
...   return None
...
>>> def test_bisect():
...   return binary_search_bisect(lst, val)
...
>>> t3 = timeit.timeit("test_bisect()", setup="from __main__ import test_bisect")
>>> t3
1.3453236258177412

对比之前,我们可以看到用bisect模块的二分查找的性能比循环二分查找快一倍。再来对比一下,如果用Python原生的list.index()的性能

>>> def test_index():
...   return lst.index(val)
...
>>> t4 = timeit.timeit("test_index()", setup="from __main__ import test_index")
>>> t4
518.1656223725007

可以看到,如果用Python原生的list.index()执行1000000,需要500秒,相比之前的二分查找,性能简直慢到恐怖

用bisect.insort插入新元素

排序很耗时,因此在得到一个有序序列之后,我们最好能够保持它的有序。bisect.insort就是为这个而存在的

insort(seq, item)把变量item插入到序列seq中,并能保持seq的升序顺序

import random
from random import randint
import bisect
 
lst = []
SIZE = 10
random.seed(5)
for _ in range(SIZE):
  item = randint(1, SIZE)
  bisect.insort(lst, item)
  print('%2d ->' % item, lst)

输出:

10 -> [10]
 5 -> [5, 10]
 6 -> [5, 6, 10]
 9 -> [5, 6, 9, 10]
 1 -> [1, 5, 6, 9, 10]
 8 -> [1, 5, 6, 8, 9, 10]
 4 -> [1, 4, 5, 6, 8, 9, 10]
 1 -> [1, 1, 4, 5, 6, 8, 9, 10]
 3 -> [1, 1, 3, 4, 5, 6, 8, 9, 10]
 2 -> [1, 1, 2, 3, 4, 5, 6, 8, 9, 10]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python制作最美应用的爬虫
Oct 28 Python
python字符串连接方法分析
Apr 12 Python
pandas 数据结构之Series的使用方法
Jun 21 Python
Pytorch中的variable, tensor与numpy相互转化的方法
Oct 10 Python
python-视频分帧&amp;多帧合成视频实例
Dec 10 Python
python实现异常信息堆栈输出到日志文件
Dec 26 Python
Python 字节流,字符串,十六进制相互转换实例(binascii,bytes)
May 11 Python
Jmeter HTTPS接口测试证书导入过程图解
Jul 22 Python
PyCharm2020.1.1与Python3.7.7的安装教程图文详解
Aug 07 Python
详解Python openpyxl库的基本应用
Feb 26 Python
python第三方网页解析器 lxml 扩展库与 xpath 的使用方法
Apr 06 Python
详解Python+OpenCV绘制灰度直方图
Mar 22 Python
pytorch中tensor张量数据类型的转化方式
Dec 31 #Python
Pytorch之parameters的使用
Dec 31 #Python
使用TensorFlow-Slim进行图像分类的实现
Dec 31 #Python
Pytorch之view及view_as使用详解
Dec 31 #Python
window环境pip切换国内源(pip安装异常缓慢的问题)
Dec 31 #Python
如何基于Python创建目录文件夹
Dec 31 #Python
Pytorch之contiguous的用法
Dec 31 #Python
You might like
PHILIPS D1835/D1875的电路分析与打理
2021/03/02 无线电
PHP在linux上执行外部命令的方法
2017/02/06 PHP
Laravel 模型使用软删除-左连接查询-表起别名示例
2019/10/24 PHP
JS+CSS实现简易实用的滑动门菜单效果
2015/09/18 Javascript
javascript手风琴下拉菜单实现代码
2015/11/12 Javascript
JavaScript中的return语句简单介绍
2015/12/07 Javascript
javascript鼠标右键菜单自定义效果
2020/12/08 Javascript
javascript实现平滑无缝滚动
2020/08/09 Javascript
Bootstrap布局方式详解
2016/05/27 Javascript
JavaScript的==运算详解
2016/07/20 Javascript
Javascript中this绑定的3种方法与比较
2016/10/13 Javascript
纯JavaScript手写图片轮播代码
2016/10/20 Javascript
JS实现页面进入和返回定位到具体位置
2016/12/08 Javascript
React Native实现进度条弹框的示例代码
2017/07/17 Javascript
微信小程序云开发如何实现数据库自动备份实现
2019/08/16 Javascript
element-ui如何防止重复提交的方法步骤
2019/12/09 Javascript
node.js Promise对象的使用方法实例分析
2019/12/26 Javascript
Python中encode()方法的使用简介
2015/05/18 Python
python如何发布自已pip项目的方法步骤
2018/10/09 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
浅析python redis的连接及相关操作
2019/11/07 Python
TensorFLow 变量命名空间实例
2020/02/11 Python
keras自动编码器实现系列之卷积自动编码器操作
2020/07/03 Python
HTML5学习笔记之html5与传统html区别
2016/01/06 HTML / CSS
跨域修改iframe页面内容详解
2019/10/31 HTML / CSS
html5 datalist 选中option选项后的触发事件
2020/03/05 HTML / CSS
Daisy London官网:英国最大的首饰集团IBB旗下
2019/02/28 全球购物
Myholidays美国:在线旅游网站
2019/08/16 全球购物
生日主持词
2014/03/20 职场文书
工伤事故赔偿协议书(标准)
2014/09/29 职场文书
2015年乡镇财政工作总结
2015/05/19 职场文书
特种设备安全管理制度
2015/08/06 职场文书
python自动化调用百度api解决验证码
2021/04/13 Python
自定义函数实现单词排序并运用于PostgreSQL(实现代码)
2021/04/22 PostgreSQL
MySQL系列之十三 MySQL的复制
2021/07/02 MySQL
nginx实现动静分离的方法示例
2021/11/07 Servers