【问题标题】:Python: how to mutate a subset of dictionary values?Python:如何改变字典值的子集?
【发布时间】:2018-03-09 22:41:56
【问题描述】:

我已经创建了字典d。我只想更改某种类型的值。例如,我想用它们的长度替换字符串。

执行此操作的无聊方法是使用 for 循环:

for k,v in d.items():
    if isinstance(v, str):
        d[k] = len(v)

但是循环不是很慢吗?
它可以通过理解来完成。我认为这相当于上面的:

d = {k: len(v) if isinstance(v, str) else v for k,v in d.items()}

我用地图试过了,但这些都不起作用(显然是因为我不懂something about tuple unpacking in Python 3):

d = dict(map(lambda k,v: (k, len(v) if isinstance(v, str) else v), d.items()))
d = dict(map(lambda (k,v): (k, len(v) if isinstance(v, str) else v), d.items()))

这似乎可行,但它变得又大又丑:

dict(map(lambda kv: (kv[0], len(kv[1]) if isinstance(kv[1], str) else kv[1]), d.items()))

这种操作好像很常见,但是我找不到具体的答案。
什么是正确、Pythonic 和高性能的方法?

【问题讨论】:

  • 您的dict 理解是正确的,恕我直言是实现这一目标的pythonic 方式。
  • for 循环不会创建新字典,只会替换那些以字符串为值的项目。理解创建一个新字典并设置每个元素,包括那些具有非字符串作为值的元素。您问循环是否很慢,但是当您需要处理一组值中的每个项目时,别无选择。理解不是魔术。它也是一个循环。
  • @PaulCornelius 哇,不是魔术吗?不,我只是想也许它在幕后更优化。所以for 循环可能更快?还是使用更少的内存?
  • 在其他条件相同的情况下,您总是更喜欢理解而不是 for 循环。但是,如果您的字典中有一百万个项目并且其中只有两个是字符串,则推导式将执行 999,998 个不必要的副本,而 for 循环只会替换 2 个值。所以像 comprehension=fast, for loop=slow 这样的规则太简单了。
  • @P1h3r1e3d13 在这种情况下,for-loop 肯定会使用更少的内存,实际上,它使用的内存量是恒定的,而不是需要 O(n) 内存的理解。但即使你的循环完全等同于理解,即它会构建一个新的dict而不是修改一个现有的,那么你也只能期望边际速度增益。理解应该是首选,主要是为了可读性。

标签: python dictionary for-loop dictionary-comprehension


【解决方案1】:

你已经有了答案,CoryKramer 已经提到过了。

d = {k: len(v) if isinstance(v, str) else v for k,v in d.items()}

这样做是最干净的方式。

【讨论】:

    猜你喜欢
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2011-04-26
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多