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函数嵌套实例
Sep 23 Python
python批量制作雷达图的实现方法
Jul 26 Python
详解Python的Lambda函数与排序
Oct 25 Python
python 将字符串转换成字典dict的各种方式总结
Mar 23 Python
Python实现的计算马氏距离算法示例
Apr 03 Python
python pandas 如何替换某列的一个值
Jun 09 Python
python bmp转换为jpg 并删除原图的方法
Oct 25 Python
全面了解django的缓存机制及使用方法
Jul 22 Python
Python threading的使用方法解析
Aug 28 Python
python继承threading.Thread实现有返回值的子类实例
May 02 Python
python中os.path.join()函数实例用法
May 26 Python
python工具dtreeviz决策树可视化和模型可解释性
Mar 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
IIS6.0+PHP5.x+MySQL5.x+Zend3.0x+GD+phpMyAdmin2.8x通用安装实例(已经完成)
2006/12/06 PHP
Windows2003 下 MySQL 数据库每天自动备份
2006/12/21 PHP
PHP 引用是个坏习惯
2010/03/12 PHP
php数组函数序列之array_pop() - 删除数组中的最后一个元素
2011/11/07 PHP
php中 ob_start等函数截取标准输出的方法
2015/06/22 PHP
PHP接口并发测试的方法(推荐)
2016/12/15 PHP
JavaScript 反科里化 this [译]
2012/09/20 Javascript
jQuery中get和post方法传值测试及注意事项
2014/08/08 Javascript
Javascript 判断两个IP是否在同一网段实例代码
2016/11/28 Javascript
利用策略模式与装饰模式扩展JavaScript表单验证功能
2017/02/14 Javascript
解决vue js IOS H5focus无法自动弹出键盘的问题
2018/08/30 Javascript
在vue 中使用 less的教程详解
2018/09/26 Javascript
JavaScript函数式编程(Functional Programming)组合函数(Composition)用法分析
2019/05/22 Javascript
AntV F2和vue-cli构建移动端可视化视图过程详解
2019/10/08 Javascript
关于vue利用postcss-pxtorem进行移动端适配的问题
2019/11/20 Javascript
[19:15]DK战队纪录片
2014/09/02 DOTA
[49:41]NB vs NAVI Supermajor小组赛A组 BO3 第一场 6.2
2018/06/03 DOTA
python开发之函数定义实例分析
2015/11/12 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
Python闭包函数定义与用法分析
2018/07/20 Python
python 搜索大文件的实例代码
2019/07/08 Python
linux环境下Django的安装配置详解
2019/07/22 Python
python 装饰器的基本使用
2021/01/13 Python
CSS3文本换行word-wrap解决英文文本超过固定宽度不换行
2013/10/10 HTML / CSS
俄罗斯香水和化妆品网上商店:NOTINO.ru
2019/12/17 全球购物
应付会计岗位职责
2013/12/12 职场文书
大学生职业生涯设计书
2014/01/02 职场文书
村捐赠仪式答谢词
2014/01/21 职场文书
自荐信需注意事项
2014/01/25 职场文书
英语简历自我评价
2014/01/26 职场文书
入党积极分子自我鉴定范文
2014/03/25 职场文书
暑期教师培训方案
2014/06/07 职场文书
篮球友谊赛通讯稿
2014/10/10 职场文书
2015年重阳节主持词
2015/07/04 职场文书
大学副班长竞选稿
2015/11/21 职场文书
Java获取字符串编码格式实现思路
2022/09/23 Java/Android