在Python中,如何遍历字典并更改等于值的值?


76

如果值为None,我想将其更改为“”(空字符串)。

我像这样开始,但是我忘记了:

for k, v in mydict.items():
    if v is None:
... right?

Answers:


140
for k, v in mydict.iteritems():
    if v is None:
        mydict[k] = ''

在更一般的情况下,例如,如果要添加或删除键,则更改正在循环的容器的结构可能并不安全-因此使用循环遍历items其独立列表副本可能是谨慎的做法-但在给定的现有索引上分配不同的值不会引起任何问题,因此,在Python 2.any中,最好使用iteritems

但是在Python3中,代码给出了AttributeError: 'dict' object has no attribute 'iteritems'错误。使用items()代替iteritems()这里。

请参阅这篇文章。


1
@John,它适用于任何内置容器-列表和字典同样适用-我认为“索引”比“键”更通用。
Alex Martelli '02

2
mydict[k] = ''-您的示例将k索引更新为不可变的对象''。因此,在此之后,k将指向与完全不同的对象v。这会k以某种方式引起索引变化.iteritems()吗?
CivFan 2015年

4
@ CivFan,nope,更改或重新分配(与相对)不会给带来问题dict.iteritems
亚历克斯·马丁里

嗯...我想知道是否.items在添加/删除键时用于循环的建议是否谨慎。我不知道dict_items对象的实现细节 ,但是如果要添加/删除键,似乎在python3.x中遍历它们可能仍然存在问题。在这种情况下,遍历密钥列表可能是最安全的: for k in list(mydict): v = mydict[k]; ...
mgilson

15

您可以只对值为None的元素创建dict理解,然后更新回原始元素:

tmp = dict((k,"") for k,v in mydict.iteritems() if v is None)
mydict.update(tmp)

更新-做过一些性能测试

好吧,在尝试使用100到10,000个项目的dict,并使用不同的None值百分比之后,Alex的解决方案的性能是该解决方案的整体速度的两倍。


嗯,对于Python 2.7,我看到的性能差不多(尽管Alex的方法始终总是更快)。我尝试了具有1000 .. 100000值和无百分比从2到50 %%的字典;为了进行比较,该方法从巴克利(与S /项目/ iteritems /)为约慢4倍。我认为这很有趣,因为您的表单允许在迭代时更改字典。
ジョージ

9

理解通常更快,并且具有mydict在迭代过程中不进行编辑的优点:

mydict = dict((k, v if v else '') for k, v in mydict.items())

如果您使用的.items()话,对于python2而言,这并不重要(对于python2),mydict因为.items()即使添加/删除了mydict
John La Rooy的

4
仅更改dict中的值从来都不是问题。悲伤是由迭代字典时添加/删除KEY引起的。理解比什么更快?速度非常快:如果要更改一两个,则复制整个字典。说到“无”,您应该if v is not None代替if v(重新阅读问题)。总体摘要:-1
John Machin

您的解决方案将布尔值上下文中的0(空列表)和所有False替换为''。我建议替换if vif v is None,这也更符合PEP 8:python.org/dev/peps/pep-0008/#programming-recommendations
Statistic Dean,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.