首页 > 解决方案 > 字典中项目的累积总和

问题描述

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

X = [{"t":1, "a":1, "b":3},
     {"t":2, "a":2, "b":4}]

如何得到:

[{"t":1, "a":1, "b":3}, {"t":2, "a":3, "b":7}]

在所需输出的第二个元素中, 的值"b"7,它是到该点的值的累积总和,"b"对于其他键也是如此。

我知道我可以通过 pandas 做到这一点。但是有没有更pythonic的解决方案?

标签: python

解决方案


collections.Counter您可以使用对象以您想要累积的方式更新的事实:

import collections


def cumulative_elementwise_sum(ds):
    result = collections.Counter()
    for d in ds:
        result.update(d)
        yield dict(result)

当遇到新密钥时,这也将“做正确的事”。例子:

>>> x = [
...    {'t': 1, 'a': 1, 'b': 3},
...    {'t': 2, 'a': 2, 'b': 4},
...    {'t': 1, 'a': 4, 'b': 1, 'd': 2},
... ]
>>> list(cumulative_elementwise_sum(x))
[{'t': 1, 'a': 1, 'b': 3},
 {'t': 3, 'a': 3, 'b': 7},
 {'t': 4, 'a': 7, 'b': 8, 'd': 2}]

如果您使用的是 Python 3.8,则该iteratools.accumulate方法已获得一个initial参数,因此可以将其简化为:

def updated(c, items):
    c.update(items)
    return c

map(dict, itertools.accumulate(x, updated, initial=collections.Counter()))

如果您只需要最终结果,而不是整个中间结果序列,则可以使用 获得functools.reduce,当然:

import functools

>>> functools.reduce(updated, x, collections.Counter())
Counter({'t': 4, 'a': 7, 'b': 8, 'd': 2})

# dict version
>>> dict(functools.reduce(updated, x, collections.Counter()))
{'t': 4, 'a': 7, 'b': 8, 'd': 2}

推荐阅读