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获取脚本所在目录的正确方法
Apr 15 Python
Python函数中定义参数的四种方式
Nov 30 Python
Python中的错误和异常处理简单操作示例【try-except用法】
Jul 25 Python
centos 安装python3.6环境并配置虚拟环境的详细教程
Feb 22 Python
python数据处理 根据颜色对图片进行分类的方法
Dec 08 Python
用Python编写一个高效的端口扫描器的方法
Dec 20 Python
使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件及出现问题解决方法
Sep 06 Python
python网络爬虫 CrawlSpider使用详解
Sep 27 Python
Python Sympy计算梯度、散度和旋度的实例
Dec 06 Python
Python如何测试stdout输出
Aug 10 Python
PyQt5 QDockWidget控件应用详解
Aug 12 Python
详解Python中的路径问题
Sep 02 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 翻页 实例代码
2009/08/07 PHP
PHP 如何利用phpexcel导入数据库
2013/08/24 PHP
innerHTML 和 getElementsByName 在IE下面的bug 的解决
2010/04/09 Javascript
jQuery的实现原理的模拟代码 -2 数据部分
2010/08/01 Javascript
查看图片(前进后退)功能实现js代码
2013/04/24 Javascript
jquery的相对父元素和相对文档定位示例代码
2013/08/02 Javascript
javascript间隔刷新的简单实例
2013/11/14 Javascript
Node.js开发之访问Redis数据库教程
2015/01/14 Javascript
仅30行代码实现Javascript中的MVC
2016/02/15 Javascript
浅谈Angularjs link和compile的使用区别
2016/10/21 Javascript
jQuery 如何实现一个滑动按钮开关
2016/12/01 Javascript
利用adb shell和node.js实现抖音自动抢红包功能(推荐)
2018/02/22 Javascript
JavaScript实现创建自定义对象的常用方式总结
2018/07/09 Javascript
配置node服务器并且链接微信公众号接口配置步骤详解
2019/06/21 Javascript
在vue中使用jsx语法的使用方法
2019/09/30 Javascript
Python采集腾讯新闻实例
2014/07/10 Python
Python基于递归算法实现的走迷宫问题
2017/08/04 Python
Python网络编程之TCP套接字简单用法示例
2018/04/09 Python
配置 Pycharm 默认 Test runner 的图文教程
2018/11/30 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
2019/03/18 Python
python3使用matplotlib绘制条形图
2020/03/25 Python
python定时复制远程文件夹中所有文件
2019/04/30 Python
python 轮询执行某函数的2种方式
2020/05/03 Python
python中pivot()函数基础知识点
2021/01/03 Python
深入解析HTML5 Canvas控制图形矩阵变换的方法
2016/03/24 HTML / CSS
HTML5 video进入全屏和退出全屏的实现方法
2020/07/28 HTML / CSS
Ray-Ban雷朋太阳眼镜英国官网:Ray-Ban UK
2019/11/23 全球购物
Claire’s法国:时尚配饰、美容、珠宝、头发
2021/01/16 全球购物
C++面试题目
2013/06/25 面试题
元旦联欢会主持词
2014/03/26 职场文书
股东合作协议书
2014/09/12 职场文书
2014年班级工作总结
2014/11/14 职场文书
2016幼儿园中班开学寄语
2015/12/03 职场文书
2016年安全生产先进个人事迹材料
2016/02/29 职场文书
传单、海报早OUT了,另类传单营销方案送给你!
2019/07/15 职场文书
阿里云服务器搭建Php+Apache运行环境的详细过程
2021/05/15 PHP