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下进行UDP网络编程的教程
Apr 29 Python
Python简单定义与使用二叉树示例
May 11 Python
python使用zip将list转为json的方法
Dec 31 Python
解决项目pycharm能运行,在终端却无法运行的问题
Jan 19 Python
Django JWT Token RestfulAPI用户认证详解
Jan 23 Python
python使用KNN算法识别手写数字
Apr 25 Python
对PyQt5的输入对话框使用(QInputDialog)详解
Jun 25 Python
pycharm new project变成灰色的解决方法
Jun 27 Python
Django框架表单操作实例分析
Nov 04 Python
关于Pytorch的MNIST数据集的预处理详解
Jan 10 Python
Python reversed函数及使用方法解析
Mar 17 Python
filter使用python3代码进行迭代元素的实例详解
Dec 03 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
星际争霸 Starcraft 游戏介绍
2020/03/14 星际争霸
PHP获取指定时间段之间的 年,月,天,时,分,秒
2016/06/05 PHP
ThinkPHP5分页paginate代码实例解析
2020/11/10 PHP
Ajax一统天下之Dojo整合篇
2007/03/24 Javascript
JavaScript入门教程(11) js事件处理
2009/01/31 Javascript
用js做一个小游戏平台 (一)
2009/12/29 Javascript
jquery属性过滤选择器使用示例
2013/06/18 Javascript
可自己添加html的伪弹出框实现代码
2013/09/08 Javascript
如何实现textarea里的不同文本显示不同颜色
2014/01/20 Javascript
JavaScript给url网址进行encode编码的方法
2015/03/18 Javascript
基于JavaScript实现仿京东图片轮播效果
2015/11/06 Javascript
基于jquery实现页面滚动时顶部导航显示隐藏
2020/04/20 Javascript
JavaScript常用字符串与数组扩展函数小结
2016/04/24 Javascript
jquery获取img的src值的简单实例
2016/05/17 Javascript
最常用的jQuery表单验证(简单)
2017/05/23 jQuery
浅谈react+es6+webpack的基础配置
2017/08/09 Javascript
微信小程序日历弹窗选择器代码实例
2019/05/09 Javascript
使用Angular9和TypeScript开发RPG游戏的方法
2020/03/25 Javascript
js+canvas绘制图形验证码
2020/09/21 Javascript
Nuxt 嵌套路由nuxt-child组件用法(父子页面组件的传值)
2020/11/05 Javascript
总结python爬虫抓站的实用技巧
2016/08/09 Python
详解python eval函数的妙用
2017/11/16 Python
Ubuntu配置Pytorch on Graph (PoG)环境过程图解
2020/11/19 Python
纯CSS实现预加载动画效果
2017/09/06 HTML / CSS
一份全面的PHP面试问题考卷
2012/07/15 面试题
C#公司笔试题
2014/03/28 面试题
电气自动化大学生求职信
2013/10/16 职场文书
关爱留守儿童倡议书
2014/04/15 职场文书
园艺师求职信
2014/04/27 职场文书
中学生的1000字检讨书
2014/10/11 职场文书
购房委托书
2014/10/15 职场文书
英语通知范文
2015/04/22 职场文书
本科毕业论文致谢怎么写
2015/05/14 职场文书
勇敢的心观后感
2015/06/09 职场文书
公文格式,规则明细(新手收藏)
2019/07/23 职场文书
mysql的数据压缩性能对比详情
2021/11/07 MySQL