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运行的17个时新手常见错误小结
Aug 07 Python
Windows和Linux下使用Python访问SqlServer的方法介绍
Mar 10 Python
Python中利用sqrt()方法进行平方根计算的教程
May 15 Python
利用python代码写的12306订票代码
Dec 20 Python
Python数据结构之翻转链表
Feb 25 Python
Python中正则表达式详解
May 17 Python
Python安装Flask环境及简单应用示例
May 03 Python
浅谈Python中函数的定义及其调用方法
Jul 19 Python
详解用Python为直方图绘制拟合曲线的两种方法
Aug 21 Python
Python中的单下划线和双下划线使用场景详解
Sep 09 Python
Django单元测试中Fixtures的使用方法
Feb 26 Python
matplotlib jupyter notebook 图像可视化 plt show操作
Apr 24 Python
使用pycharm运行flask应用程序的详细教程
只用Python就可以制作的简单词云
python通过函数名调用函数的几种方法总结
Jun 07 #Python
Python爬虫实战之爬取京东商品数据并实实现数据可视化
Python实现的扫码工具居然这么好用!
Jun 07 #Python
忆童年!用Python实现愤怒的小鸟游戏
python单元测试之pytest的使用
Jun 07 #Python
You might like
如何使用PHP批量去除文件UTF8 BOM信息
2013/08/05 PHP
php文件上传的例子及参数详解
2013/12/12 PHP
win7安装php框架Yii的方法
2016/01/25 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
php和html的区别点详细总结
2019/09/24 PHP
TP5框架使用QueryList采集框架爬小说操作示例
2020/03/26 PHP
对于Form表单reset方法的新认识
2014/03/05 Javascript
zepto.js中tap事件阻止冒泡的实现方法
2015/02/12 Javascript
jQuery插件HighCharts实现的2D堆条状图效果示例【附demo源码下载】
2017/03/14 Javascript
Bootstrap DateTime Picker日历控件简单应用
2017/03/25 Javascript
详解vue2.0的Element UI的表格table列时间戳格式化
2017/06/13 Javascript
详解Node.js利用node-git-server快速搭建git服务器
2017/09/27 Javascript
node跨域转发 express+http-proxy-middleware的使用
2018/05/31 Javascript
ng-repeat指令在迭代对象时的去重方法
2018/10/02 Javascript
vue input实现点击按钮文字增删功能示例
2019/01/29 Javascript
JSON.stringify()方法讲解
2019/01/31 Javascript
修改NPM全局模式的默认安装路径的方法
2020/12/15 Javascript
[49:43]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
python去掉字符串中重复字符的方法
2014/02/27 Python
Python的Flask框架的简介和安装方法
2015/11/13 Python
Python中Collections模块的Counter容器类使用教程
2016/05/31 Python
python实现对csv文件的列的内容读取
2018/07/04 Python
用Python编写一个简单的CS架构后门的方法
2018/11/20 Python
python 实现围棋游戏(纯tkinter gui)
2020/11/13 Python
分布式全文检索引擎ElasticSearch原理及使用实例
2020/11/14 Python
HTML5实现一个能够移动的小坦克示例代码
2013/09/02 HTML / CSS
美国打印机墨水和碳粉购物网站:QuikShip Toner
2018/08/29 全球购物
Python中pass语句的作用是什么
2016/06/01 面试题
当文件系统受到破坏时,如何检查和修复系统?
2012/03/09 面试题
基层工作经历证明
2014/01/13 职场文书
一年级班主任寄语
2014/01/19 职场文书
职工年度考核评语
2014/12/31 职场文书
优秀英文求职信范文
2015/03/19 职场文书
安全生产警示教育活动总结
2015/05/09 职场文书
节水宣传标语口号
2015/12/26 职场文书
详解 TypeScript 枚举类型
2021/11/02 Javascript