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获取apk文件URL地址实例
Nov 01 Python
python动态加载变量示例分享
Feb 17 Python
Python中的Numeric包和Numarray包使用教程
Apr 13 Python
python 专题九 Mysql数据库编程基础知识
Mar 16 Python
遗传算法python版
Mar 19 Python
Python3自动签到 定时任务 判断节假日的实例
Nov 13 Python
Python实现计算字符串中出现次数最多的字符示例
Jan 21 Python
解决Python中定时任务线程无法自动退出的问题
Feb 18 Python
Django实现学员管理系统
Feb 26 Python
python3 配置logging日志类的操作
Apr 08 Python
基于Tensorflow的MNIST手写数字识别分类
Jun 17 Python
pycharm2021激活码使用教程(永久激活亲测可用)
Mar 30 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读取网页文件内容的实现代码(fopen,curl等)
2011/06/23 PHP
php中使用接口实现工厂设计模式的代码
2012/06/17 PHP
php session_start()出错原因分析及解决方法
2013/10/28 PHP
YII CLinkPager分页类扩展增加显示共多少页
2016/01/29 PHP
记录Yii2框架开发微信公众号遇到的问题及解决方法
2018/07/20 PHP
Laravel5.5+ 使用API Resources快速输出自定义JSON方法详解
2020/04/06 PHP
为jQuery添加Webkit的触摸的方法分享
2014/02/02 Javascript
jQuery的animate函数学习记录
2014/08/08 Javascript
node.js中的forEach()是同步还是异步呢
2015/01/29 Javascript
Javascript中的匿名函数与封装介绍
2015/03/15 Javascript
js实现从右向左缓缓浮出网页浮动层广告的方法
2015/05/09 Javascript
js光标定位文本框回车表单提交问题的解决方法
2015/05/11 Javascript
Vue.js实现简单动态数据处理
2017/02/13 Javascript
zTree获取当前节点的下一级子节点数实例
2017/09/05 Javascript
Bootstrap table使用方法汇总
2017/11/17 Javascript
Vue Cli3 创建项目的方法步骤
2018/10/15 Javascript
React 路由懒加载的几种实现方案
2018/10/23 Javascript
VUE实现自身整体组件销毁的示例代码
2020/01/13 Javascript
详解Vue数据驱动原理
2020/11/17 Javascript
[09:37]2018DOTA2国际邀请赛寻真——不懈追梦的Team Serenity
2018/08/13 DOTA
Python面向对象编程中的类和对象学习教程
2015/03/30 Python
深入解析Python中的__builtins__内建对象
2016/06/21 Python
Python实现读取并保存文件的类
2017/05/11 Python
Python学习笔记之if语句的使用示例
2017/10/23 Python
python3将视频流保存为本地视频文件
2018/06/20 Python
python实现网页自动签到功能
2019/01/21 Python
Django如何实现防止XSS攻击
2020/10/13 Python
Python web框架(django,flask)实现mysql数据库读写分离的示例
2020/11/18 Python
美国知名的旅游网站:OneTravel
2018/10/09 全球购物
财务内勤岗位职责
2014/04/17 职场文书
廉洁家庭事迹材料
2014/05/15 职场文书
无犯罪记录证明
2014/09/19 职场文书
入党后的感想
2015/08/10 职场文书
诚实守信主题班会
2015/08/13 职场文书
Html分层的box-shadow效果的示例代码
2021/03/30 HTML / CSS
golang json数组拼接的实例
2021/04/28 Golang