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编程中一些重用与缩减的建议
Apr 14 Python
简单的python后台管理程序
Apr 13 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
Sep 11 Python
利用numpy实现一、二维数组的拼接简单代码示例
Dec 15 Python
python中返回矩阵的行列方法
Apr 04 Python
浅谈python中对于json写入txt文件的编码问题
Jun 07 Python
使用 Python 实现微信群友统计器的思路详解
Sep 26 Python
Python实现的特征提取操作示例
Dec 03 Python
python实现网页自动签到功能
Jan 21 Python
Python后台开发Django会话控制的实现
Apr 15 Python
python标准库OS模块详解
Mar 10 Python
Pycharm2020.1安装中文语言插件的详细教程(不需要汉化)
Aug 07 Python
使用pycharm运行flask应用程序的详细教程
只用Python就可以制作的简单词云
python通过函数名调用函数的几种方法总结
Jun 07 #Python
Python爬虫实战之爬取京东商品数据并实实现数据可视化
Python实现的扫码工具居然这么好用!
Jun 07 #Python
忆童年!用Python实现愤怒的小鸟游戏
python单元测试之pytest的使用
Jun 07 #Python
You might like
PHP压缩html网页代码(清除空格,换行符,制表符,注释标记)
2012/04/02 PHP
php事务处理实例详解
2014/07/11 PHP
在textarea文本域中显示HTML代码的方法
2007/03/06 Javascript
jquery选择器之层级过滤选择器详解
2014/01/27 Javascript
JavaScript利用构造函数和原型的方式模拟C#类的功能
2014/03/06 Javascript
调试代码导致IE出错的避免方法
2014/04/04 Javascript
JQuery记住用户名和密码的具体实现
2014/04/04 Javascript
js实现最短的XML格式化工具实例
2015/03/12 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
2015/12/03 Javascript
JavaScript数组合并的多种方法
2016/05/22 Javascript
js实现千分符和保留几位小数的简单实例
2016/08/01 Javascript
IScroll5实现下拉刷新上拉加载的功能实例
2017/08/11 Javascript
Node.js EventEmmitter事件监听器用法实例分析
2019/01/07 Javascript
vue中引入mxGraph的步骤详解
2019/05/17 Javascript
如何使用50行javaScript代码实现简单版的call,apply,bind
2019/08/14 Javascript
vue实现二级导航栏效果
2019/10/19 Javascript
如何利用 JS 脚本实现网页全自动秒杀抢购功能
2020/10/12 Javascript
[47:04]EG vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
如何利用Boost.Python实现Python C/C++混合编程详解
2018/11/08 Python
Python3爬虫爬取百姓网列表并保存为json功能示例【基于request、lxml和json模块】
2018/12/05 Python
python配置grpc环境
2019/01/01 Python
Python time库基本使用方法分析
2019/12/13 Python
Python实现封装打包自己写的代码,被python import
2020/07/12 Python
python打包多类型文件的操作方法
2020/09/21 Python
浅析几个CSS3常用功能的写法
2014/06/05 HTML / CSS
html5中的input新属性range使用记录
2014/09/05 HTML / CSS
澳大利亚在线性感内衣商店:Fantasy Lingerie
2021/02/07 全球购物
软件测试面试题
2014/01/05 面试题
团支书的期末学习总结自我评价
2013/11/01 职场文书
英语教师岗位职责
2014/03/16 职场文书
2014年五四青年节活动策划书
2014/04/22 职场文书
关于教师节的广播稿
2014/09/10 职场文书
个性发展自我评价2015
2015/03/09 职场文书
2015年老干部工作总结
2015/04/23 职场文书
2015年统计员个人工作总结
2015/07/23 职场文书
十大必看国产动漫排名,魁拔上线,第二曾在日本播出
2022/03/18 国漫