Python字典和列表性能之间的比较


Posted in Python onJune 07, 2021

Python列表和字典

  • 前面我们了解了 “大O表示法” 以及对不同的算法的评估,下面来讨论下 Python 两种内置数据类型有关的各种操作的大O数量级:列表 list 和字典dict。
  • 这是 Python 中两种非常重要的数据类型,后面会用来实现各种数据结构,通过运行试验来估计其各种操作运行时间数量级。

对比 list 和 dict 操作如下:

Python字典和列表性能之间的比较

List列表数据类型常用操作性能:

最常用的是:按索引取值和赋值(v=a[i],a[i]=v),由于列表的随机访问特性,这两个操作执行时间与列表大小无关,均为O(1)。

另一个是列表增长,可以选择 append() 和 “+”:lst.append(v),执行时间是O(1);lst= lst+ [v],执行时间是O(n+k),其中 k 是被加的列表长度,选择哪个方法来操作列表,也决定了程序的性能。

测试 4 种生成 n 个整数列表的方法:

Python字典和列表性能之间的比较

创建一个 Timer 对象,指定需要反复运行的语句和只需要运行一次的"安装语句"。

然后调用这个对象的 timeit 方法,指定反复运行多少次。

# Timer(stmt="pass", setup="pass")   # 这边只介绍两个参数
# stmt:statement的缩写,就是要测试的语句,要执行的对象
# setup:导入被执行的对象(就和run代码前,需要导入包一个道理) 在主程序命名空间中  导入
time1 = Timer("test1()", "from __main__ import test1") 
print("concat:{} seconds".format(time1.timeit(1000)))
time2 = Timer("test2()", "from __main__ import test2")
print("append:{} seconds".format(time2.timeit(1000)))
time3 = Timer("test3()", "from __main__ import test3")
print("comprehension:{} seconds".format(time3.timeit(1000)))
time4 = Timer("test4()", "from __main__ import test4")
print("list range:{} seconds".format(time4.timeit(1000))

结果如下:

Python字典和列表性能之间的比较

可以看到,4种方法运行时间差别挺大的,列表连接(concat)最慢,List range最快,速度相差近 100 倍。append要比 concat 快得多。另外,我们注意到列表推导式速度大约是 append 两倍的样子。

总结列表基本操作的大 O 数量级:

Python字典和列表性能之间的比较

我们注意到 pop 这个操作,pop()是从列表末尾移除元素,时间复杂度为O(1);pop(i)从列表中部移除元素,时间复杂度为O(n)。
原因在于 Python 所选择的实现方法,从中部移除元素的话,要把移除元素后面的元素,全部向前挪位复制一遍,这个看起来有点笨拙
但这种实现方法能够保证列表按索引取值和赋值的操作很快,达到O(1)。这也算是一种对常用和不常用操作的折中方案。

list.pop()的计时试验,通过改变列表的大小来测试两个操作的增长趋势:

import timeit

pop_first = timeit.Timer("x.pop(0)", "from __main__ import x")
pop_end = timeit.Timer("x.pop()", "from __main__ import x")
print("pop(0)          pop()")
y_1 = []
y_2 = []
for i in range(1000000, 10000001, 1000000):
    x = list(range(i))
    p_e = pop_end.timeit(number=1000)
    x = list(range(i))
    p_f = pop_first.timeit(number=1000)
    print("{:.6f}        {:.6f}".format(p_f, p_e))
    y_1.append(p_f)
    y_2.append(p_e)

结果如下:

Python字典和列表性能之间的比较

将试验结果可视化,可以看出增长趋势:pop()是平坦的常数,pop(0)是线性增长的趋势。

Python字典和列表性能之间的比较

字典与列表不同,是根据键值(key)找到数据项,而列表是根据索引(index)。最常用的取值和赋值,其性能均为O(1)。另一个重要操作contains(in)是判断字典中是否存在某个键值(key),这个性能也是O(1)。

Python字典和列表性能之间的比较

做一个性能测试试验来验证 list 中检索一个值,以及 dict 中检索一个值的用时对比,生成包含连续值的 list 和包含连续键值 key 的
dict,用随机数来检验操作符 in 的耗时。

import timeit
import random

y_1 = []
y_2 = []
print("lst_time         dict_time")
for i in range(10000, 1000001, 25000):
    t = timeit.Timer("random.randrange(%d) in x" % i, "from __main__ import random, x")
    x = list(range(i))
    lst_time = t.timeit(number=1000)
    x = {j: 'k' for j in range(i)}
    dict_time = t.timeit(number=1000)
    print("{:.6f}        {:.6f}".format(lst_time, dict_time))
    y_1.append(lst_time)
    y_2.append(dict_time)

结果如下:

Python字典和列表性能之间的比较
Python字典和列表性能之间的比较

  • 可见字典的执行时间与规模无关,是常数。
  • 而列表的执行时间则会随着列表的规模加大而线性上升。

更多 Python 数据类型操作复杂度可以参考官方文档:
https://wiki.python.org/moin/TimeComplexity

到此这篇关于Python字典和列表性能之间的比较的文章就介绍到这了,更多相关Python列表和字典内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python操作RabbitMQ服务器实现消息队列的路由功能
Jun 29 Python
Python实现的简单模板引擎功能示例
Sep 02 Python
从django的中间件直接返回请求的方法
May 30 Python
python3 拼接字符串的7种方法
Sep 12 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
Nov 21 Python
Python功能点实现:函数级/代码块级计时器
Jan 02 Python
python3 tkinter实现点击一个按钮跳出另一个窗口的方法
Jun 13 Python
Django框架基础模板标签与filter使用方法详解
Jul 23 Python
Python多线程获取返回值代码实例
Feb 17 Python
基于Python pyecharts实现多种图例代码解析
Aug 10 Python
详解Python为什么不用设计模式
Jun 24 Python
用PYTHON去计算88键钢琴的琴键频率和音高
Apr 10 Python
使用pycharm运行flask应用程序的详细教程
只用Python就可以制作的简单词云
python通过函数名调用函数的几种方法总结
Jun 07 #Python
Python爬虫实战之爬取京东商品数据并实实现数据可视化
Python实现的扫码工具居然这么好用!
Jun 07 #Python
忆童年!用Python实现愤怒的小鸟游戏
python单元测试之pytest的使用
Jun 07 #Python
You might like
smarty实例教程
2006/11/19 PHP
数据库中排序的对比及使用条件详解
2012/02/23 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
PHP程序员基本要求和必备技能
2014/05/09 PHP
图解找出PHP配置文件php.ini的路径的方法
2014/08/20 PHP
Ubuntu下安装PHP的mongodb扩展操作命令
2015/07/04 PHP
php根据年月获取当月天数及日期数组的方法
2016/11/30 PHP
php数组指针函数功能及用法示例
2020/02/11 PHP
jquery配合css简单实现返回顶部效果
2013/09/30 Javascript
jquery实现简单易懂的图片展示小例子
2013/11/21 Javascript
原生javascript模仿win8等待提示圆圈进度条
2014/04/24 Javascript
JavaScript设计模式经典之命令模式
2016/02/24 Javascript
javascript检测移动设备横竖屏
2016/05/21 Javascript
js内置对象处理_打印学生成绩单的简单实现
2016/09/24 Javascript
Vue.js开发环境搭建
2016/11/10 Javascript
AngularJS ui-router (嵌套路由)实例
2017/03/10 Javascript
node.js爬虫爬取拉勾网职位信息
2017/03/14 Javascript
详解angular element()方法使用
2017/04/08 Javascript
React-Native实现ListView组件之上拉刷新实例(iOS和Android通用)
2017/07/11 Javascript
Vue的土著指令和自定义指令实例详解
2018/02/04 Javascript
vue封装可复用组件confirm,并绑定在vue原型上的示例
2019/10/31 Javascript
JS Html转义和反转义(html编码和解码)的实现与使用方法总结
2020/03/10 Javascript
快速解决element的autofocus失效问题
2020/09/08 Javascript
[37:37]DAC2018 4.4 淘汰赛 Optic vs Mineski 第二场
2018/04/05 DOTA
放弃 Python 转向 Go语言有人给出了 9 大理由
2017/10/20 Python
CentOS7.3编译安装Python3.6.2的方法
2018/01/22 Python
分析python动态规划的递归、非递归实现
2018/03/04 Python
Python实现接受任意个数参数的函数方法
2018/04/21 Python
Django+Ajax+jQuery实现网页动态更新的实例
2018/05/28 Python
python psutil模块使用方法解析
2019/08/01 Python
纯CSS实现聊天框小尖角、气泡效果
2014/04/04 HTML / CSS
标记环介质访问控制协议
2016/03/27 面试题
教师节活动主持词
2014/04/02 职场文书
大三学习计划书范文
2014/05/02 职场文书
2015年员工试用期工作总结
2015/05/28 职场文书
HTML CSS 一个标签实现带动画的抖音LOGO
2022/04/26 HTML / CSS