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的装饰器解决Bottle框架中用户验证问题
Apr 24 Python
python计算方程式根的方法
May 07 Python
python计算文本文件行数的方法
Jul 06 Python
简单掌握Python的Collections模块中counter结构的用法
Jul 07 Python
Python实现抓取网页生成Excel文件的方法示例
Aug 05 Python
利用Django内置的认证视图实现用户密码重置功能详解
Nov 24 Python
对python3 urllib包与http包的使用详解
May 10 Python
Python开发之Nginx+uWSGI+virtualenv多项目部署教程
May 13 Python
Python定时任务随机时间执行的实现方法
Aug 14 Python
Python列表解析操作实例总结
Feb 26 Python
python实现电子词典
Mar 03 Python
Python爬虫之Selenium鼠标事件的实现
Dec 04 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入门小知识
2008/03/24 PHP
将博客园(cnblogs.com)数据导入到wordpress的代码
2013/01/06 PHP
PHP登录环节防止sql注入的方法浅析
2014/06/30 PHP
php中header跳转使用include包含解决参数丢失问题
2015/05/08 PHP
php查询whois信息的方法
2015/06/08 PHP
PHP实时统计中文字数和区别
2019/02/28 PHP
jQuery的初始化与对象构建之浅析
2011/04/12 Javascript
使用CSS和jQuery模拟select并附提交后取得数据的代码
2013/10/18 Javascript
JavaScript学习笔记(三):JavaScript也有入口Main函数
2015/09/12 Javascript
使用Jasmine和Karma对AngularJS页面程序进行测试
2016/03/05 Javascript
Vue.js开发环境搭建
2016/11/10 Javascript
JS组件系列之MVVM组件 vue 30分钟搞定前端增删改查
2017/04/28 Javascript
Bootstrap table使用方法总结
2017/05/10 Javascript
vuejs+element-ui+laravel5.4上传文件的示例代码
2017/08/12 Javascript
JS解决position:sticky的兼容性问题的方法
2017/10/17 Javascript
浅谈React 服务器端渲染的使用
2018/05/08 Javascript
Vue 项目分环境打包的方法示例
2018/08/03 Javascript
微信小程序module.exports模块化操作实例浅析
2018/12/20 Javascript
js正则匹配多个全部数据问题
2019/12/20 Javascript
解决ant Design Search无法输入内容的问题
2020/10/29 Javascript
vue中父子组件的参数传递和应用示例
2021/01/04 Vue.js
[05:36]DOTA2 2015国际邀请赛中国区预选赛第四日TOP10
2015/05/29 DOTA
Python构造自定义方法来美化字典结构输出的示例
2016/06/16 Python
django rest framework之请求与响应(详解)
2017/11/06 Python
Python简单读取json文件功能示例
2017/11/30 Python
详解python中的Turtle函数库
2018/11/19 Python
简单了解python中对象的取反运算符
2019/07/01 Python
pytorch实现focal loss的两种方式小结
2020/01/02 Python
tensorflow之tf.record实现存浮点数数组
2020/02/17 Python
Nginx+Uwsgi+Django 项目部署到服务器的思路详解
2020/05/08 Python
Java ExcutorService优雅关闭方式解析
2020/05/30 Python
abstract class和interface有什么区别
2013/08/04 面试题
医院后勤自我鉴定
2013/10/13 职场文书
小学生手册家长评语
2014/04/16 职场文书
Go 语言中 20 个占位符的整理
2021/10/16 Golang
《LOL》“克隆大作战”久违归来 幻灵战队皮肤上线
2022/04/03 其他游戏