You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python字典聚合问题:functools.reduce为何忽略负数值?

问题解答

为什么代码会移除负数值对应的键

这个问题和functools.reduce、operator.add本身没有关系,核心原因是**collections.Counter重写的__add__方法有特殊设计逻辑**:

Counter实例执行加法操作时,只会保留最终计数结果大于0的键,结果小于等于0的键会被直接丢弃。

你示例中154对应的值为-0.1,在Counter相加过程中最终结果为负,因此被自动过滤,这是Counter的专属特性,和普通数值加法的逻辑不一致。

可实现期望输出的替代方案

方案1:collections.defaultdict遍历累加

逻辑最清晰直观,天然兼容正负值:

from collections import defaultdict

d = [{152: 1}, {151: 3}, {152: 4}, {153: 5}, {153: 10}, {154: -0.1}]
res = defaultdict(float)
for item in d:
    for k, v in item.items():
        res[k] += v
# 如需输出普通字典可加下行
res = dict(res)

运行结果为{152: 5, 151: 3, 153: 15, 154: -0.1},完全符合预期。

方案2:functools.reduce自定义合并逻辑

如果偏好函数式写法,可以避开Counter的加法规则,自己定义合并逻辑:

import functools

d = [{152: 1}, {151: 3}, {152: 4}, {153: 5}, {153: 10}, {154: -0.1}]
res = functools.reduce(lambda a, b: {k: a.get(k, 0) + b.get(k, 0) for k in {*a, *b}}, d)

方案3:Counter的update方法实现

如果需要使用Counter,可调用不会过滤负值的update方法实现:

from collections import Counter

d = [{152: 1}, {151: 3}, {152: 4}, {153: 5}, {153: 10}, {154: -0.1}]
res = Counter()
for item in d:
    # update为直接累加操作,不会过滤负值
    res.update(item)
# 如需输出普通字典可加下行
res = dict(res)

内容的提问来源于stack exchange,提问作者koyamashinji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 14:54:03