遍历字典或其键并更改值是否是错误的做法?

时间:2019-01-25 10:40:48

标签: python dictionary iteration

在python 2中,我使用了:

d = {'a': 1, 'b': 2, 'c': 3}
for k in d.keys():
    d[k] = d[k] * 2
print(d)
# {'a': 2, 'b': 4, 'c': 6}

在python 3中,我使用:

d = {'a': 1, 'b': 2, 'c': 3}
for k in d:
    d[k] = d[k] * 2
print(d)
# {'a': 2, 'b': 4, 'c': 6}

这种新语法使我感觉到我正在遍历某些东西(字典)并对其进行修改,这很不好。但实际上,我只是遍历键,所以应该不会带来任何麻烦,对吧?

2 个答案:

答案 0 :(得分:6)

遍历字典并修改值非常好。每次调用dict.__getitem__ / dict.__setitem__或分别调用其语法糖dict[] / dict[] = ...时,都会检索一个键的值。您可以在迭代项目时覆盖键的值,因为更改值不会更改键哈希,因此不会影响迭代器。

不是的好处是,当您遍历字典视图时添加或删除键。有问题的原因是given in the docs

  

dict.keys()dict.values()dict.items()返回的对象   是视图对象。它们提供了词典的动态视图   条目,这意味着当词典更改时,视图   反映这些变化。

答案 1 :(得分:1)

如果您不更改字典的键集,那么我不认为这是不好的做法。您的示例没有这样做,所以很好。

如果您的更改涉及添加或删除元素,事情就会变得混乱:

d = {}
k = d.keys()
i = iter(k)
d[42] = 23
next(i)

这将引发异常:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

通过遍历项目而不是键,可以稍微改善您的示例:

d = dict(a=1, b=2, c=3)
for k, v in d.items():
    d[k] = v * 2

,或者在您的“只是加倍”的特殊情况下:

for k in d.keys():
    d[k] *= 2

但是我想您的实际用例可能更复杂。

编辑:请注意,如果您仍在使用Python2,则应使用.iteritems().iterkeys()而不是.items().keys()