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的Scrapy框架编写web爬虫的简单示例
Apr 17 Python
Python中顺序表的实现简单代码分享
Jan 09 Python
Python3中的json模块使用详解
May 05 Python
python pandas库中DataFrame对行和列的操作实例讲解
Jun 09 Python
python 叠加等边三角形的绘制的实现
Aug 14 Python
Python如何实现动态数组
Nov 02 Python
Jupyter 无法下载文件夹如何实现曲线救国
Apr 22 Python
Python实现EM算法实例代码
Oct 04 Python
Python偏函数实现原理及应用
Nov 20 Python
python如何发送带有附件、正文为HTML的邮件
Feb 27 Python
pytorch 带batch的tensor类型图像显示操作
May 20 Python
分享Python获取本机IP地址的几种方法
Mar 17 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实现实时生成并下载超大数据量的EXCEL文件详解
2017/10/23 PHP
PHP7 新增常量
2021/03/09 PHP
Javascript 面向对象 对象(Object)
2010/05/13 Javascript
js实现双向链表互联网机顶盒实战应用实现
2011/10/28 Javascript
由Javascript实现的页面日历
2011/11/04 Javascript
JavaScript高级程序设计 读书笔记之十 本地对象Date日期
2012/02/27 Javascript
转义字符(\)对JavaScript中JSON.parse的影响概述
2013/07/17 Javascript
判断客户浏览器是否支持cookie的示例代码
2013/12/23 Javascript
JavaScript数组函数unshift、shift、pop、push使用实例
2014/08/27 Javascript
js获取UserControl内容为拼html时提供方便
2014/11/02 Javascript
JavaScript中使用指数方法Math.exp()的简介
2015/06/15 Javascript
深入理解JQuery循环绑定事件
2016/06/02 Javascript
AngularJS ng-app 指令实例详解
2016/07/30 Javascript
js实现适合新闻类图片的轮播效果
2017/02/05 Javascript
JavaScript实现实时更新系统时间的实例代码
2017/04/04 Javascript
如何将 jQuery 从你的 Bootstrap 项目中移除(取而代之使用Vue.js)
2017/07/17 jQuery
angular2 ng2 @input和@output理解及示例
2017/10/10 Javascript
Element Backtop回到顶部的具体使用
2020/07/27 Javascript
Vue前端判断数据对象是否为空的实例
2020/09/02 Javascript
Python编程实现二叉树及七种遍历方法详解
2017/06/02 Python
python使用numpy读取、保存txt数据的实例
2018/10/14 Python
python学生信息管理系统(完整版)
2020/04/05 Python
python/Matplotlib绘制复变函数图像教程
2019/11/21 Python
python实现高斯判别分析算法的例子
2019/12/09 Python
python 线性回归分析模型检验标准--拟合优度详解
2020/02/24 Python
python图片指定区域替换img.paste函数的使用
2020/04/09 Python
你对IPv6了解程度
2016/02/09 面试题
银行员工职业规划范文
2014/01/21 职场文书
文明餐桌行动实施方案
2014/02/19 职场文书
元旦活动感言
2014/03/08 职场文书
领导班子民主生活会整改措施(工商局)
2014/09/21 职场文书
学校纪律作风整改措施思想汇报
2014/10/11 职场文书
幼儿园托班开学寄语(2016秋季)
2015/12/03 职场文书
Python编程编写完善的命令行工具
2021/09/15 Python
Python+Tkinter打造签名设计工具
2022/04/01 Python
Python OpenCV超详细讲解读取图像视频和网络摄像头
2022/04/02 Python