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]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 明达年度发烧碟MasterSuperiorAudiophile2021[DSF]
- 英文DJ 《致命的温柔》24K德国HD金碟DTS 2CD[WAV+分轨][1.7G]
- 张学友1997《不老的传说》宝丽金首版 [WAV+CUE][971M]
- 张韶涵2024 《不负韶华》开盘母带[低速原抓WAV+CUE][1.1G]
- lol全球总决赛lcs三号种子是谁 S14全球总决赛lcs三号种子队伍介绍
- lol全球总决赛lck三号种子是谁 S14全球总决赛lck三号种子队伍
- 群星.2005-三里屯音乐之男孩女孩的情人节【太合麦田】【WAV+CUE】
- 崔健.2005-给你一点颜色【东西音乐】【WAV+CUE】
- 南台湾小姑娘.1998-心爱,等一下【大旗】【WAV+CUE】
- 【新世纪】群星-美丽人生(CestLaVie)(6CD)[WAV+CUE]
- ProteanQuartet-Tempusomniavincit(2024)[24-WAV]
- SirEdwardElgarconductsElgar[FLAC+CUE]
- 田震《20世纪中华歌坛名人百集珍藏版》[WAV+CUE][1G]
- BEYOND《大地》24K金蝶限量编号[低速原抓WAV+CUE][986M]
- 陈奕迅《准备中 SACD》[日本限量版] [WAV+CUE][1.2G]