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的tkinter布局之简单的聊天窗口实现方法
Sep 03 Python
深入浅析ImageMagick命令执行漏洞
Oct 11 Python
Python爬虫DNS解析缓存方法实例分析
Jun 02 Python
Python中join函数简单代码示例
Jan 09 Python
详解Python自建logging模块
Jan 29 Python
Python装饰器用法实例总结
May 26 Python
Python3中函数参数传递方式实例详解
May 05 Python
详解python中的数据类型和控制流
Aug 08 Python
Pandas之缺失数据的实现
Jan 06 Python
python爬虫scrapy基本使用超详细教程
Feb 20 Python
python 模拟在天空中放风筝的示例代码
Apr 21 Python
基于PyQT5制作一个桌面摸鱼工具
Feb 15 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
如何用C语言编写PHP扩展的详解
2013/06/13 PHP
Drupal7 form表单二次开发要点与实例
2014/03/02 PHP
destoon调用discuz论坛中带图片帖子的实现方法
2014/08/21 PHP
Laravel 5框架学习之数据库迁移(Migrations)
2015/04/08 PHP
PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)
2016/11/15 PHP
详谈PHP中public,private,protected,abstract等关键字的用法
2017/12/31 PHP
JQuery 获取和设置Select选项的代码
2010/02/07 Javascript
jQuery图片播放8款精美插件分享
2013/02/17 Javascript
JavaScript简单实现网页回到顶部功能
2013/11/12 Javascript
JS 屏蔽按键效果与改变按键效果的示例代码
2013/12/24 Javascript
浅谈javascript中的instanceof和typeof
2015/02/27 Javascript
学习Bootstrap组件之下拉菜单
2015/07/28 Javascript
JavaScript必看小技巧(必看)
2016/06/07 Javascript
js实现当鼠标移到表格上时显示这一格全部内容的代码
2016/06/12 Javascript
浅谈JavaScript的闭包函数
2016/12/08 Javascript
Bootstrap实现圆角、圆形头像和响应式图片
2016/12/14 Javascript
微信小程序日历效果
2018/12/29 Javascript
vue中过滤器filter的讲解
2019/01/21 Javascript
JS获取动态添加元素的方法详解
2019/07/31 Javascript
[06:49]2018DOTA2国际邀请赛寻真——VirtusPro傲视群雄
2018/08/12 DOTA
[40:19]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第二场 12.18
2020/12/19 DOTA
通过数据库对Django进行删除字段和删除模型的操作
2015/07/21 Python
Python获取基金网站网页内容、使用BeautifulSoup库分析html操作示例
2019/06/04 Python
Python利用神经网络解决非线性回归问题实例详解
2019/07/19 Python
PyQt5基本控件使用详解:单选按钮、复选框、下拉框
2019/08/05 Python
浅谈Python_Openpyxl使用(最全总结)
2019/09/05 Python
Flask中endpoint的理解(小结)
2019/12/11 Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
2020/01/03 Python
Python脚本实现Zabbix多行日志监控过程解析
2020/08/26 Python
css3的transform中scale缩放详解
2014/12/08 HTML / CSS
商务英语本科生的自我评价分享
2013/11/15 职场文书
教师党的群众路线教育实践活动个人整改措施
2014/11/04 职场文书
2014三年级班主任工作总结
2014/12/05 职场文书
工作经验交流材料
2014/12/30 职场文书
小学生班干部竞选稿
2015/11/20 职场文书
V Rising 服务器搭建图文教程
2022/06/16 Servers