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清除指定目录内所有文件中script的方法
Jun 30 Python
Python查询阿里巴巴关键字排名的方法
Jul 08 Python
关于Django ForeignKey 反向查询中filter和_set的效率对比详解
Dec 15 Python
Python+OpenCV感兴趣区域ROI提取方法
Jan 10 Python
Python os.access()用法实例
Feb 18 Python
Python对接六大主流数据库(只需三步)
Jul 31 Python
Python进程,多进程,获取进程id,给子进程传递参数操作示例
Oct 11 Python
Pandas+Matplotlib 箱式图异常值分析示例
Dec 09 Python
彻底搞懂python 迭代器和生成器
Sep 07 Python
python用opencv 图像傅里叶变换
Jan 04 Python
Python接口自动化系列之unittest结合ddt的使用教程详解
Feb 23 Python
详解python的xlwings库读写excel操作总结
Feb 26 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
php插入排序法实现数组排序实例
2015/02/16 PHP
php实现和c#一致的DES加密解密实例
2017/07/24 PHP
由prototype_1.3.1进入javascript殿堂-类的初探
2006/11/06 Javascript
Javascript中判断变量是数组还是对象(array还是object)
2013/08/14 Javascript
控制文字内容的显示与隐藏示例
2014/06/11 Javascript
Javascript基础教程之if条件语句
2015/01/18 Javascript
超赞的动手创建JavaScript框架的详细教程
2015/06/30 Javascript
使用ES6语法重构React代码详解
2017/05/09 Javascript
基于BootStrap实现简洁注册界面
2017/07/20 Javascript
使用Vue组件实现一个简单弹窗效果
2018/04/23 Javascript
Vue 组件传值几种常用方法【总结】
2018/05/28 Javascript
vue elementui form表单验证的实现
2018/11/11 Javascript
[05:09]2016国际邀请赛中国区预选赛淘汰赛首日精彩回顾
2016/06/29 DOTA
[48:32]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 LGD vs VG
2018/04/01 DOTA
[01:35:53]完美世界DOTA2联赛PWL S3 Magma vs GXR 第二场 12.13
2020/12/17 DOTA
Python按行读取文件的实现方法【小文件和大文件读取】
2016/09/19 Python
python脚本替换指定行实现步骤
2017/07/11 Python
Python基于回溯法子集树模板解决0-1背包问题实例
2017/09/02 Python
Python cookbook(数据结构与算法)从字典中提取子集的方法示例
2018/03/22 Python
Centos 升级到python3后pip 无法使用的解决方法
2018/06/12 Python
Opencv+Python 色彩通道拆分及合并的示例
2018/12/08 Python
分享Python切分字符串的一个不错方法
2018/12/14 Python
详解Python连接MySQL数据库的多种方式
2019/04/16 Python
python视频按帧截取图片工具
2019/07/23 Python
python使用bs4爬取boss直聘静态页面
2020/10/10 Python
体育专业学生自我评价范文
2014/01/17 职场文书
《风筝》教学反思
2014/04/10 职场文书
英语一分钟演讲稿
2014/04/29 职场文书
个人安全承诺书
2014/05/22 职场文书
美化环境标语
2014/06/20 职场文书
学习优秀党员杨宗兴先进事迹材料思想汇报
2014/09/14 职场文书
岗位职责范本大全
2015/02/26 职场文书
2015年保洁员工作总结
2015/05/04 职场文书
反腐倡廉观后感
2015/06/08 职场文书
车辆挂靠协议书
2016/03/23 职场文书
三年级作文之趣事作文
2019/11/04 职场文书