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中bisect的使用方法的更多相关文章

  1. python中List的sort方法的用法

    python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. 关键字: python列表排序 python字典排序 sorted List的元素可以是各种东 ...

  2. 【转】python中List的sort方法(或者sorted内建函数)的用法

    原始出处:http://gaopenghigh.iteye.com/blog/1483864 python列表排序 简单记一下python中List的sort方法(或者sorted内建函数)的用法. ...

  3. 【转】关于python中re模块split方法的使用

    注:最近在研究文本处理,需要用到正则切割文本,所以收索到了这篇文章,很有用,谢谢原作者. 原址:http://blog.sciencenet.cn/blog-314114-775285.html 关于 ...

  4. 查看python中模块的所有方法

    查看python中模块的所有方法     安装的python模块,现将查看方法总结如下 一.CMD命令行下使用pydoc命令 在命令行下运行$ pydoc modules即可查看 二.在python交 ...

  5. Python中bisect的使用

    在<Think Python>中第十章的练习中,涉及到了分半查找的bisect模块.为此,在网上查阅了Python中bisect模块的相关内容.有几个链接相对权威和明白: 1> ht ...

  6. PySpark 的背后原理--在Driver端,通过Py4j实现在Python中调用Java的方法.pyspark.executor 端一个Executor上同时运行多少个Task,就会有多少个对应的pyspark.worker进程。

    PySpark 的背后原理 Spark主要是由Scala语言开发,为了方便和其他系统集成而不引入scala相关依赖,部分实现使用Java语言开发,例如External Shuffle Service等 ...

  7. python中requests库使用方法详解

    目录 python中requests库使用方法详解 官方文档 什么是Requests 安装Requests库 基本的GET请求 带参数的GET请求 解析json 添加headers 基本POST请求 ...

  8. 全面了解python中的类,对象,方法,属性

    全面了解python中的类,对象,方法,属性 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...

  9. python中列表元素连接方法join用法实例

    python中列表元素连接方法join用法实例 这篇文章主要介绍了python中列表元素连接方法join用法,实例分析了Python中join方法的使用技巧,非常具有实用价值,分享给大家供大家参考. ...

随机推荐

  1. hibernate课程 初探单表映射3-4 组件属性

    本节内容: 1 简介组件属性 2 demo 1 简介组件属性: <component name = "address" class = "Address" ...

  2. Jquery里面的$(this)和this, 有什么区别

    当你用的是jquery时,就用$(this),如果是JS,就用this $(this).html( $(this).html() + " BAM! "); 这个里的html()是J ...

  3. Mysql数据库操作语句总结(三)

    最近一段时间重新学习一下mysql命令行的用法, 这里简单记录一下 参考文章: https://www.cnblogs.com/bluealine/p/7832219.html 个人使用的是mysql ...

  4. javascript设计模式之外观模式

    /* * 外观模式 * 外观模式的主要意义在于简化类的接口,使其易于调用 */ // 你常常在不经意中使用了外观模式,尤其类库中更多(处理兼容性问题) var addEvent = function ...

  5. <转载>为什么VR不可能成功?

    这是一个来自Quora的回答,我把要点总结翻译了下,供大家参考批判. How big and issue the nausea problem for Virtual Reality products ...

  6. [SVN]TortoiseSVN报“500 Internal Server Error”错误的解决方法

    背景:由于某种原因,本人重启了一下SVN服务的物理机,重启过后发现所有人访问SVN都报如下错误. 由于重启之前是没有做过任何改动,所以面对这个错误有点摸不着头脑,防火墙.网管.清缓存等方法都试过,还没 ...

  7. fastjson解析json数组

    1.fastjson解析json数组(直接上代码) import java.util.ArrayList; import java.util.List; import com.alibaba.fast ...

  8. LeetCode Nim Game (简单nim)

    题意: 有一堆石子,里面有n个石头,每次可以从中取出1~3个,两人轮流取,最后一个石子被谁取走即为赢家.你先取,问最后谁赢? 思路: n%4>0则先手赢,因为每次总是可以给对方留4个石子的倍数, ...

  9. 使用后台程序的第一个表单Form

    参考手册:http://www.yiichina.com/doc/guide/2.0/start-forms 1.创建模型:advanced\backend\models\moxing.php 此模型 ...

  10. pta 编程题8 Tree Traversals Again

    其它pta数据结构编程题请参见:pta 这次的作业考察的是树的遍历. 题目的输入通过栈的pop给出了树的中序遍历的顺序.根据push和pop的顺序构造树的方法为:定义一个变量father来确定父节点, ...