一段关于Python字典遍历的“争论”
2013-03-05 11:36
190 查看
一段关于Python字典遍历的“争论”
Posted on 2010年10月31日6,249 阅读小弟我今天吃饱了饭逛大神们的blog,发现bones的某篇日志下面这么一段小小的争论。
先摘抄下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #这里初始化一个dict >>> d= {'a':1,'b':0,'c':1,'d':0} #本意是遍历dict,发现元素的值是0的话,就删掉 >>> fork ind: ... if d[k]== 0: ... del(d[k]) ... Traceback (mostrecent call last): File"<stdin>", line 1,in <module> RuntimeError: dictionary changedsize duringiteration #结果抛出异常了,两个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常量。 >>> fork ind.keys(): ... if d[k]== 0: ... del(d[k]) ... >>> d {'a':1, 'c': 1} #结果也是对的 >>> |
bones的解决方法是遍历字典键值,以字典键值为依据遍历,这样改变了value以后不会影响遍历继续。
但是下面又有一位大神抛出高论:
。首先,python 是推荐使用迭代器的,也就是 for k in adict 形式。其次,在遍历中删除容器中的元素,在 C++ STL 和 Python 等库中,都是不推荐的,因为这种情况往往说明了你的设计方案有问题,所有都有特殊要求,对应到 python 中,就是要使用 adict.key() 做一个拷贝。最后,所有的 Python 容器都不承诺线程安全,你要多线程做这件事,本身就必须得加锁,这也说明了业务代码设计有问题的
但由“遍历中删除特定元素”这种特例,得出“遍历dict的时候,养成使用 for k in d.keys() 的习惯”,我觉得有必要纠正一下。在普通的遍历中,应该使用 for k in adict。
另外,对于“遍历中删除元素”这种需求,pythonic 的做法是 adict = {k, v for adict.iteritems() if v != 0} 或 alist = [i for i in alist if i != 0]
这个写法让我眼前一亮:怎么还有这个语法?
再仔细一看,他可能是这个意思:
#!/usr/bin/env python
# -*- coding=utf-8 -*-
a = {'a':1, 'b':0, 'c':1, 'd':0}
b={}
for k,v in a.items():
if v != 0:
b.update({k:v})
adict = b
del b
print a
1 2 3 4 5 6 7 8 9 10 | #!/usr/bin/env python # -*- coding=utf-8 -*- a= {'a':1,'b':0,'c':1,'d':0} b={} fork,vin a.items(): if v!= 0: b.update({k:v}) adict =b delb print a |
因为这个写法一开始让我猛然想到三元操作符,仔细一看才发现不是,以前Goolge到有个解决方案
val = float(raw_input("Age: "))
status = ("working","retired")[val>65]
print "You should be",status
1 2 3 | val= float(raw_input("Age: ")) status =("working","retired")[val>65] print"You should be",status |
不过在Google的资料里面还有一个版本
#V1 if X else V2
s = None
a = "not null" if s == None else s
print a
#'not null'
1 2 3 4 5 | #V1 if X else V2 s =None a= "not null"if s== Noneelse s print a #'not null' |
>>> alist = [1,2,0,3,0,4,5]
>>> alist = [i for i in alist if i != 0]
>>> alist
[1, 2, 3, 4, 5]
>>> d = {'a':1, 'b':0, 'c':1, 'd':0}
>>> d = dict([(k,v) for k,v in d.iteritems() if v!=0])
>>> d
{'a':1,'c':1'}
如果大于Python>=2.7
还可以用这个写法:
>>> d = {k:v for k,v in d.iteritems() if v !=0 }
也就是赖勇浩原文里面提到的语法
原文:http://blog.ihipop.info/2010/10/1777.html
相关文章推荐
- 一段关于Python字典遍历的“争论”
- Python中字典遍历的争论
- python关于列表转为字典的两个小方法
- python字典遍历方法总结
- python字典键值对的添加和遍历方法
- python 字典(dict)遍历四种方法的性能
- 关于python中字典的一些总结
- python遍历删除字典里值为空的元素报错
- 详解python中字典的循环遍历的两种方式
- Python实现字典的遍历与排序功能示例
- Python数据结构(一)关于字典
- Python简单遍历字典及删除元素的方法
- Python中遍历字典过程中更改元素导致异常的解决方法
- python中str(字符串)、list(列表)、tuple(元组)、dict(字典)相互转化关系及字典键-值遍历
- 关于python中字典的一些总结
- python 中字典的遍历
- Python多维/嵌套字典数据无限遍历
- Python 遍历字典
- 关于Python数据结构中字典的心得
- Python -- 遍历字典时删除元素报异常