【问题标题】:Get a new dictionary with the same keys using reduce function with a lambda argument使用带有 lambda 参数的 reduce 函数获取具有相同键的新字典
【发布时间】:2021-12-27 10:42:55
【问题描述】:

我有一个这样的字典列表。

fruit = [{"apple": 10, "pear": 20, "banana": 30, "strawberry": 50},
{"apple": 12, "pear": 5, "banana": 20, "strawberry": 5},
{"apple": 15, "pear": 26, "banana": 32, "strawberry": 8}]

我可以在一行中编写一个 reduce 函数(使用 lambda 参数)来获得一个具有相同键的新字典。新字典的每个键的值是对应键的所有值的总和。预期的输出应该是一个字典,如下所示:

{'apple': 37.0, 'pear': 51.0, 'banana': 82.0, 'strawberry': 63.0}

【问题讨论】:

  • 我想这是可能的,但可能有点笨拙。你有没有尝试过……?
  • 为什么要写成一行?您可以通过用; 分隔任意数量的语句将它们放入同一行,但您不应该这样做,因为它会损害代码的可读性。您也可以在单个语句中执行此操作,但这也会损害可读性。

标签: python dictionary lambda


【解决方案1】:

实用方法:

from operator import add
from collections import Counter
from functools import reduce

reduce(add, map(Counter, fruit))
# Counter({'banana': 82, 'strawberry': 63, 'pear': 51, 'apple': 37})

或者对初学者更有启发性,为两个字典写一个add

def add(d1, d2):
    return {k: d1.get(k, 0) + d2.get(k, 0) for k in d1.keys() | d2.keys()}

reduce(add, fruit)

【讨论】:

    【解决方案2】:

    字典理解可以像这样合并两个字典:

    >>> from functools import reduce
    >>> fruit = [{"apple": 10, "pear": 20, "banana": 30, "strawberry": 50},
    ...          {"apple": 12, "pear": 5, "banana": 20, "strawberry": 5},
    ...          {"apple": 15, "pear": 26, "banana": 32, "strawberry": 8}]
    >>> reduce(lambda a, b: {k: a[k] + v for k, v in b.items()}, fruit)
    {'apple': 37, 'pear': 51, 'banana': 82, 'strawberry': 63}
    

    这确实要求所有 dicts 具有相同的键,否则会丢弃一些。更完整的版本是这样的,但它作为 reduce-lambda 确实变得相当笨拙:

    reduce(lambda a, b: {k: a.get(k, 0) + b.get(k, 0) for k in a.keys() | b.keys()}, fruit)
    

    【讨论】:

    • 您可以使用a.get(k, 0) + b.get(k, 0) for k in a.keys() | b.keys() 来保留密钥。
    • 是的,我只是添加了它,但我不会向任何人推荐它。
    【解决方案3】:

    以下方法使用 dict 理解且不导入。但是我不建议使用它:

    {k: sum(f.get(k,0) for f in fruit) for k in {k for f in fruit for k in f}}
    #                                           |                           |
    #                                           +-- set of all fruit keys --+
    

    【讨论】:

      猜你喜欢
      • 2011-11-25
      • 1970-01-01
      • 1970-01-01
      • 2019-05-11
      • 1970-01-01
      • 2015-08-19
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多