我有一个这样的字典列表:
X = [{"t":1, "a":1, "b":3},
{"t":2, "a":2, "b":4}]
Run Code Online (Sandbox Code Playgroud)
如何得到:
[{"t":1, "a":1, "b":3}, {"t":2, "a":3, "b":7}]
Run Code Online (Sandbox Code Playgroud)
在所需输出的第二个元素中, 的值为,"b"它是截至该点的值7的累积和,其他键也是如此。"b"
我知道我可以通过熊猫做到这一点。但是有没有更Pythonic的解决方案呢?
collections.Counter您可以利用对象以您想要累积的方式更新的事实:
import collections
def cumulative_elementwise_sum(ds):
result = collections.Counter()
for d in ds:
result.update(d)
yield dict(result)
Run Code Online (Sandbox Code Playgroud)
当遇到新密钥时,这也将“做正确的事情”。例子:
>>> 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}]
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 Python 3.8,该iteratools.accumulate方法已获得一个initial参数,因此可以简化为:
def updated(c, items):
c.update(items)
return c
map(dict, itertools.accumulate(x, updated, initial=collections.Counter()))
Run Code Online (Sandbox Code Playgroud)
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}
Run Code Online (Sandbox Code Playgroud)