【问题标题】:Modifying dictionary values while iterating with dict.values() or dict.itervalues()使用 dict.values() 或 dict.itervalues() 迭代时修改字典值
【发布时间】:2011-10-14 17:36:25
【问题描述】:

我有一个这样初始化的字典:

tab = {'Mike': 0, 'Chad': 15, 'Taylor': 2}

我希望能够将整数添加到字典中的每个值。
例如,添加 5 后,字典应如下所示:

{'Mike': 5, 'Chad': 20, 'Taylor': 7}

似乎这可以通过几行代码来完成,但我无法弄清楚。 我尝试了一个 for 循环:

for k in tab.itervalues():
    k = k + 5

我运行这段代码,然后打印出字典:

tab = {'Mike': 0, 'Chad': 15, 'Taylor': 2}

字典没有发生变化。我不确定 Python 是否将这些值识别为字符串或整数。

【问题讨论】:

  • k = k + 5 这行实际上是在创建一个全新的变量。你看不到它,因为 python 对你隐藏了它(这是 python 的传递对象范例的一部分)。然而,这既不是这里也不是那里。即使您可以修改 k,它也不会修改字典。有关正确方法,请参阅 waffle paradox 的答案。

标签: python dictionary iteration


【解决方案1】:

最简单的方法?

for k in tab.keys():
    tab[k] += 5

【讨论】:

  • 老实说,我发现 tab.keys() 更具可读性,但是也可以。
【解决方案2】:

tab.itervalues() 在值上创建一个迭代器。

您遍历这些,并依次传递每个值。值为ints。 在 Python 中,这些是不可变的

在 Python 中,语句 a += 3 被翻译 - 在大多数 情况下 - 为 a = a + 3a + 3 创建一个 new int 对象,对于 a 已经引用了一个 int 的情况,然后名称 a 被重新绑定到新对象。

所以你改变了迭代变量(通过重新绑定它),而不是映射中的值(因为它是不可变的)。

waffle paradox's solution 通过在键上使用迭代器来访问然后重新绑定字典中的值来解决这个问题。这很简单,Pythonic 很好。

或者,您可以拥抱不变性,并应用函数式编程范式。我们想创建一个与我们现有的字典类似但键递增的字典;并且导致tab 引用这个新字典只是偶然的。

因此:

tab = dict((k, v + 5) for (k, v) in tab.iteritems())

当您遇到基于相同基本问题的更难问题时,这种方法通常会让您的生活更轻松。

【讨论】:

  • 我的自然倾向是改变原始字典。我喜欢另一种方法,我会尽量记住它以备将来使用。
  • 现在我们可以写出更漂亮的tab = {k: v + 5 for k, v in tab.items()}
猜你喜欢
  • 1970-01-01
  • 2023-04-06
  • 2011-10-10
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 2021-03-30
  • 1970-01-01
相关资源
最近更新 更多