python两种遍历字典(dict)的方法比较


Posted in Python onMay 29, 2014

python以其优美的语法和方便的内置数据结构,赢得了不少程序员的亲睐。
其中有个很有用的数据结构,就是字典(dict),使用非常简单。说到遍历一个dict结构,我想大多数人都会想到 for key in dictobj 的方法,确实这个方法在大多数情况下都是适用的。但是并不是完全安全,请看下面这个例子:

#这里初始化一个dict
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#本意是遍历dict,发现元素的值是0的话,就删掉
>>> for k in d:
...   if d[k] == 0:
...     del(d[k])
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
#结果抛出异常了,两个0的元素,也只删掉一个。
>>> d
{'a': 1, 'c': 1, 'd': 0}>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
#d.keys() 是一个下标的数组
>>> d.keys()
['a', 'c', 'b', 'd']
#这样遍历,就没问题了,因为其实其实这里遍历的是d.keys()这个list常量。
>>> for k in d.keys():
...   if d[k] == 0:
...     del(d[k])
... 
>>> d
{'a': 1, 'c': 1}
#结果也是对的
>>>

其实,这个例子是我简化过的,我是在一个多线程的程序里发现这个问题的,所以,我的建议是:遍历dict的时候,养成使用 for k in d.keys() 的习惯。
不过,如果是多线程的话,这样就绝对安全吗?也不见得:当两个线程都取完d.keys()以后,如果两个线程都去删同一个key的话,先删的会成功,后删的那个肯定会报 KeyError ,这个看来只能通过其他方式来保证了。

另一篇:dict 两种遍历方式的性能对比

关于纠结dict遍历中带括号与不带括号的性能问题

for (d,x) in dict.items():
     print "key:"+d+",value:"+str(x)for d,x in dict.items():
    print "key:"+d+",value:"+str(x)

带括号和不带括号性能测试结果:

测试结果
测试条数:15
带括号开始时间:2012-06-14 12:13:37.375000
带括号结束时间:2012-06-14 12:13:37.375000
时间间隔:0:00:00
不带括号开始时间:2012-06-14 12:13:37.375000
不带括号结束时间:2012-06-14 12:13:37.375000
时间间隔:0:00:00
测试条数:50
带括号开始时间:2012-06-14 12:13:57.921000
带括号结束时间:2012-06-14 12:13:57.921000
时间间隔:0:00:00
不带括号开始时间:2012-06-14 12:13:57.921000
不带括号结束时间:2012-06-14 12:13:57.937000
时间间隔:0:00:00.016000
测试条数:100
带括号开始时间:2012-06-14 11:53:57.453000
带括号结束时间:2012-06-14 11:53:57.468000
时间间隔:0:00:00.015000
不带括号开始时间:2012-06-14 11:53:57.468000
不带括号结束时间:2012-06-14 11:53:57.531000
时间间隔:0:00:00.063000
测试条数:150
带括号开始时间:2012-06-14 12:00:54.812000
带括号结束时间:2012-06-14 12:00:54.828000
时间间隔:0:00:00.016000
不带括号开始时间:2012-06-14 12:00:54.828000
不带括号结束时间:2012-06-14 12:00:54.921000
时间间隔:0:00:00.093000
测试条数:200
带括号开始时间:2012-06-14 11:59:54.609000
带括号结束时间:2012-06-14 11:59:54.687000
时间间隔:0:00:00.078000
不带括号开始时间:2012-06-14 11:59:54.687000
不带括号结束时间:2012-06-14 11:59:54.734000
时间间隔:0:00:00.047000
测试条数:500
带括号开始时间:2012-06-14 11:54:39.906000
带括号结束时间:2012-06-14 11:54:40.078000
时间间隔:0:00:00.172000
不带括号开始时间:2012-06-14 11:54:40.078000
不带括号结束时间:2012-06-14 11:54:40.125000
时间间隔:0:00:00.047000
测试条数:1000
带括号开始时间:2012-06-14 11:54:49.171000
带括号结束时间:2012-06-14 11:54:49.437000
时间间隔:0:00:00.266000
不带括号开始时间:2012-06-14 11:54:49.437000
不带括号结束时间:2012-06-14 11:54:49.609000
时间间隔:0:00:00.172000
测试条数:2000
带括号开始时间:2012-06-14 11:54:58.921000
带括号结束时间:2012-06-14 11:54:59.328000
时间间隔:0:00:00.407000
不带括号开始时间:2012-06-14 11:54:59.328000
不带括号结束时间:2012-06-14 11:54:59.687000
时间间隔:0:00:00.359000
测试条数:5000
带括号开始时间:2012-06-14 11:55:05.781000
带括号结束时间:2012-06-14 11:55:06.734000
时间间隔:0:00:00.953000
不带括号开始时间:2012-06-14 11:55:06.734000
不带括号结束时间:2012-06-14 11:55:07.609000
时间间隔:0:00:00.875000
测试条数:10000
带括号开始时间:2012-06-14 11:55:15.656000
带括号结束时间:2012-06-14 11:55:17.390000
时间间隔:0:00:01.734000
不带括号开始时间:2012-06-14 11:55:17.390000
不带括号结束时间:2012-06-14 11:55:19.109000
时间间隔:0:00:01.719000
测试条数:20000
带括号开始时间:2012-06-14 12:19:14.921000
带括号结束时间:2012-06-14 12:19:18.593000
时间间隔:0:00:03.672000
不带括号开始时间:2012-06-14 12:19:18.593000
不带括号结束时间:2012-06-14 12:19:22.218000
时间间隔:0:00:03.625000

我们可以看出,dict条数在200一下的时候是带括号的性能比较高一点,但是在200条以上的数据后不带括号的执行时间会少些.

下面是测试代码:

测试Code
#-*- coding: utf-8 -*-
import datetime,codecs
dict = {}
for i in xrange(0,20000):
    dict.setdefault("name"+str(i))
    dict["name"+str(i)]="name"
s=codecs.open(r'c:\\dict.txt','a', 'utf-8')
def write(des):
    s.write(des.decode("utf-8"))
write("测试条数:")
write(str(len(dict))+"\r\n")
write("带括号开始时间:")
a=datetime.datetime.now()
s.write(str(a)+"\r\n")
for (d,x) in dict.items():
    print "key:"+d+",value:"+str(x)
write("带括号结束时间:")
b=datetime.datetime.now()
write(str(b)+"\r\n")
write("时间间隔:")
write(str(b-a)+"\r\n")
write("不带括号开始时间:")
c=datetime.datetime.now()
write(str(c)+"\r\n")
for d,x in dict.items():
    print "key:"+d+",value:"+str(x)
write("不带括号结束时间:")
d=datetime.datetime.now()
write(str(d)+"\r\n")
write("时间间隔:")
write(str(d-c)+"\r\n")
write("\r\n")
s.close()

中文乱码问题有没有很好的解决办法....?

Python 相关文章推荐
python基础教程之popen函数操作其它程序的输入和输出示例
Feb 10 Python
Python爬虫DOTA排行榜爬取实例(分享)
Jun 13 Python
python装饰器深入学习
Apr 06 Python
利用Python如何实现一个小说网站雏形
Nov 23 Python
python实现感知器算法(批处理)
Jan 18 Python
Pandas统计重复的列里面的值方法
Jan 30 Python
django-rest-framework 自定义swagger过程详解
Jul 18 Python
python tkinter canvas使用实例
Nov 04 Python
Django用户身份验证完成示例代码
Apr 03 Python
keras打印loss对权重的导数方式
Jun 10 Python
浅谈matplotlib 绘制梯度下降求解过程
Jul 12 Python
Python 详解通过Scrapy框架实现爬取CSDN全站热榜标题热词流程
Nov 11 Python
python中常用的各种数据库操作模块和连接实例
May 29 #Python
从零学Python之入门(五)缩进和选择
May 27 #Python
从零学Python之入门(四)运算
May 27 #Python
一则python3的简单爬虫代码
May 26 #Python
从零学Python之入门(三)序列
May 25 #Python
从零学Python之入门(二)基本数据类型
May 25 #Python
Python tempfile模块学习笔记(临时文件)
May 25 #Python
You might like
PHP冒泡排序算法代码详细解读
2011/07/17 PHP
Zend Studio去除编辑器的语法警告设置方法
2012/10/24 PHP
php中OR与|| AND与&amp;&amp;的区别总结
2013/10/26 PHP
php遍历CSV类实例
2015/04/14 PHP
JavaScript 错误处理与调试经验总结
2010/08/10 Javascript
Javascript类定义语法,私有成员、受保护成员、静态成员等介绍
2011/12/08 Javascript
JQuery入门——用bind方法绑定事件处理函数应用介绍
2013/02/05 Javascript
JavaScript toUpperCase()方法使用详解
2016/08/26 Javascript
AngularJs bootstrap搭载前台框架——基础页面
2016/09/01 Javascript
ionic中的$ionicPlatform.ready事件中的通用设置
2017/06/11 Javascript
JS随机排序数组实现方法分析
2017/10/11 Javascript
微信小程序websocket实现即时聊天功能
2019/05/21 Javascript
vue里的data要用return返回的原因浅析
2019/05/28 Javascript
no-vnc和node.js实现web远程桌面的完整步骤
2019/08/11 Javascript
vue中改变滚动条样式的方法
2020/03/03 Javascript
解决vue组件销毁之后计时器继续执行的问题
2020/07/21 Javascript
Python中for循环详解
2014/01/17 Python
Python常见MongoDB数据库操作实例总结
2018/07/24 Python
Python 访问限制 private public的详细介绍
2018/10/16 Python
python判断所输入的任意一个正整数是否为素数的两种方法
2019/06/27 Python
Python3 venv搭建轻量级虚拟环境的步骤(图文)
2019/08/09 Python
Python爬虫:将headers请求头字符串转为字典的方法
2019/08/21 Python
python中使用asyncio实现异步IO实例分析
2021/02/26 Python
英国最大的笔记本电脑直销专家:Laptops Direct
2019/07/20 全球购物
为什么要优先使用同步代码块而不是同步方法?
2013/01/30 面试题
node中使用shell脚本的方法步骤
2021/03/23 Javascript
汽车检测与维修应届毕业生求职信
2013/10/19 职场文书
绿色城市实施方案
2014/03/19 职场文书
学生喝酒检讨书500字
2014/11/02 职场文书
暑期社会实践证明书
2014/11/17 职场文书
汽车销售助理岗位职责
2015/04/14 职场文书
2015年青年志愿者工作总结
2015/05/20 职场文书
初中政治教学工作总结
2015/08/13 职场文书
Python如何识别银行卡卡号?
2021/06/10 Python
pandas求平均数和中位数的方法实例
2021/08/04 Python
Win11筛选键导致键盘失灵怎么解决? Win11关闭筛选键的技巧
2022/04/08 数码科技