代码之家  ›  专栏  ›  技术社区  ›  totooooo Richard Dally

重复使用dict或其键并更改值是一种坏习惯吗?

  •  2
  • totooooo Richard Dally  · 技术社区  · 6 年前

    在Python2中,我使用了:

    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}
    

    这个新的语法让我感觉我在重复一些东西(dict)并修改它,这很糟糕。但事实上,我只是迭代这些键,所以这不会带来任何麻烦,对吧?

    2 回复  |  直到 6 年前
        1
  •  6
  •   jpp    6 年前

    迭代字典并修改值是非常好的。每次你打电话 dict.__getitem__ / dict.__setitem__ 或者分别是它的句法糖 dict[] / dict[] = ... ,检索键的值。可以在迭代项时覆盖键的值,因为更改值不会更改键哈希,因此不会影响迭代器。

    什么 精细是在迭代字典视图时添加或删除键。这有问题的原因是 given in the docs :

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

        2
  •  1
  •   Alfe    6 年前

    如果你不改变字典的键集,我看不出为什么这是一种不好的做法。你的例子并没有做到这一点,所以它们很好。

    如果你的 改变 包括添加或删除元素:

    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() .

    推荐文章