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中使用异步Socket编程性能测试
Jun 25 Python
python编写网页爬虫脚本并实现APScheduler调度
Jul 28 Python
Python中使用Boolean操作符做真值测试实例
Jan 30 Python
探究数组排序提升Python程序的循环的运行效率的原因
Apr 01 Python
用Python编写一个简单的俄罗斯方块游戏的教程
Apr 03 Python
Python实现批量修改文件名实例
Jul 08 Python
Python网络爬虫项目:内容提取器的定义
Oct 25 Python
使用Python写一个小游戏
Apr 02 Python
python3+PyQt5重新实现自定义数据拖放处理
Apr 19 Python
Django中的ajax请求
Oct 19 Python
python直接获取API传递回来的参数方法
Dec 17 Python
python用海龟绘图写贪吃蛇游戏
Jun 18 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
开启CURL扩展,让服务器支持PHP curl函数(远程采集)
2011/03/19 PHP
PHP 第二节 数据类型之数组
2012/04/28 PHP
thinkphp命名空间用法实例详解
2015/12/30 PHP
PHP Try-catch 语句使用技巧
2016/02/28 PHP
ThinkPHP3.2.3实现分页的方法详解
2016/06/03 PHP
获取当前网页document.url location.href区别总结
2008/05/10 Javascript
jQuery的实现原理的模拟代码 -5 Ajax
2010/08/07 Javascript
js jquery获取随机生成id的服务器控件的三种方法
2013/07/11 Javascript
js实现温度计时间样式代码分享
2015/08/21 Javascript
js仿苹果iwatch外观的计时器代码分享
2015/08/26 Javascript
JS 对象(Object)和字符串(String)互转方法
2016/05/20 Javascript
基于JavaScript实现添加到购物车效果附源码下载
2016/08/22 Javascript
Bootstrap select下拉联动(jQuery cxselect)
2017/01/04 Javascript
将input框中输入内容显示在相应的div中【三种方法可选】
2017/05/08 Javascript
详解VUE 定义全局变量的几种实现方式
2017/06/01 Javascript
JS实现十字坐标跟随鼠标效果
2017/12/25 Javascript
微信小程序页面生命周期详解
2018/01/31 Javascript
vue实现的组件兄弟间通信功能示例
2018/12/04 Javascript
JS Ajax请求会话过期处理问题解决方法分析
2019/11/16 Javascript
javaScript代码飘红报错看不懂?读完这篇文章再试试
2020/08/19 Javascript
vant-ui组件调用Dialog弹窗异步关闭操作
2020/11/04 Javascript
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
js实现鼠标切换图片(无定时器)
2021/01/27 Javascript
python实现的简单FTP上传下载文件实例
2015/06/30 Python
在Python中画图(基于Jupyter notebook的魔法函数)
2019/10/28 Python
int和Integer有什么区别
2013/05/25 面试题
个人简历中的自我评价范例
2013/10/29 职场文书
关于安全演讲稿
2014/05/09 职场文书
单位工作证明格式模板
2014/10/04 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
领导欢迎词范文
2015/01/26 职场文书
2015小学新教师个人工作总结
2015/10/14 职场文书
先进基层党组织主要事迹材料
2015/11/03 职场文书
2016高考寄语集锦
2015/12/04 职场文书
《小乌鸦爱妈妈》教学反思
2016/02/19 职场文书
靠谱准确的求职信
2019/04/02 职场文书