添加保持零值的计数器

Posted

技术标签:

【中文标题】添加保持零值的计数器【英文标题】:Add Counters keeping zero values 【发布时间】:2020-11-14 00:50:02 【问题描述】:

我尝试将其他字典中存在的键的值与此代码相加:

import functools
import operator
import collections

my_dict = ['a':0, 'b':1, 'c':5, 'b':3, 'c':2, 'b':1, 'c':1]
sum_key_value = functools.reduce(operator.add, map(collections.Counter, my_dict))

print(sum_key_value)

# Output
# Counter('c': 8, 'b': 5)

我的问题是,如果我希望输出保留所有字典键,即使在我的情况下该键没有出现在像 a 这样的所有字典中,不使用循环的最佳方法是什么?

【问题讨论】:

***.com/questions/3490738/how-to-sum-dict-elements --- 干 Python 文档中指出,在 Counter 对象上进行添加操作(这是您的代码中发生的情况)将删除带有 0 的值:每个操作都可以接受输入签名计数,但输出将排除计数为零或更少的结果 (docs.python.org/3/library/collections.html#collections.Counter) 【参考方案1】:

使用 for 循环有很多不错的方法,但由于您特别想避免 for 循环,所以这里有一种方法:

sum_key_value = dict(functools.reduce(lambda a, b: a.update(b) or a,
                     my_dict, collections.Counter()))

所以这里发生的事情是您创建一个计数器,并使用它来累积值。

【讨论】:

【参考方案2】:

在这里,最直接的方法是循环。您可能有键出现在列表中任何位置的字典中(例如:第三个可能有键“e”),因此您至少需要一个循环来获得键的总数。然后你可以再次遍历所有字典来总结这些值。为它创建一个自己的函数,您可以调用它而无需再关心循环。

def sum_it_up(dictlist):
    outdic = 
    for d in dictlist:
        for k in d.keys():
            outdic[k] = 0
    for d in dictlist:
        for k in d.keys():
            outdic[k]+=d[k]
    return outdic

my_dict = ['a':0, 'b':1, 'c':5, 'b':3, 'c':2, 'b':1, 'c':1]
sum_key_value = sum_it_up(my_dict)

【讨论】:

【参考方案3】:

如 cmets 中所述,添加 Counter 对象将删除非正键

所以问题不在于最终不是所有键的联合(以及添加公共值),因为这确实是行为,看看我们是否设置了a:2

my_dict = ['a':2, 'b':1, 'c':5, 'b':3, 'c':2, 'b':1, 'c':1]
functools.reduce(operator.add, map(Counter, my_dict))
# Counter('a': 2, 'b': 5, 'c': 8)

但是,如问题所示,根据当前的实现,当添加 Counter 对象时,非正值 (a:0) 会被删除。

如果您真的想为此使用 Counter,您可以稍微调整 current implementation 覆盖 __add__ 以获得预期的行为:

class Counter_tweaked(Counter):
    def __add__(self, other):
            if not isinstance(other, Counter):
                return NotImplemented
            result = Counter_tweaked()
            for elem, count in self.items():
                newcount = count + other[elem]
                result[elem] = newcount
            for elem, count in other.items():
                if elem not in self:
                    result[elem] = count
            return result

functools.reduce(operator.add, map(Counter_tweaked, my_dict))
# Counter_tweaked('a': 0, 'b': 5, 'c': 8)

【讨论】:

以上是关于添加保持零值的计数器的主要内容,如果未能解决你的问题,请参考以下文章

使用 knitr 和 kable() 生成的表格控制零值的科学记数法和格式

python pandas - 创建一个保持连续值运行计数的列

如何在熊猫列中找到连续零的最大计数?

按组将唯一/不同值的计数添加到原始数据

RawFraction 性能计数器即使在删除性能类别后仍保持其状态

apache在发布请求时返回403错误,输入变量计数保持不变,值发生变化