添加计数器时如何保留我的原始字典

How to keep my original dict when doing addition of Counter

据我了解,我知道何时调用 Counter 来隐藏 dict。此字典包含键的值为零将消失。

from collections import Counter

a = {"a": 1, "b": 5, "d": 0}
b = {"b": 1, "c": 2}

print Counter(a) + Counter(b)

如果我想保留我的钥匙,怎么办?

这是我的预期结果:

Counter({'b': 6, 'c': 2, 'a': 1, 'd': 0})

不幸的是,当对两个计数器求和时,只使用计数为正的元素。

如果要保留计数为零的元素,可以定义如下函数:

def addall(a, b):
    c = Counter(a)          # copy the counter a, preserving the zero elements
    for x in b:             # for each key in the other counter
        c[x] += b[x]        # add the value in the other counter to the first
    return c

也可以使用Counter的update()方法代替+运算符,例如-

>>> a = {"a": 1, "b": 5, "d": 0}
>>> b = {"b": 1, "c": 2}
>>> x = Counter(a)
>>> x.update(Counter(b))
>>> x
Counter({'b': 6, 'c': 2, 'a': 1, 'd': 0})

update() 函数添加计数而不是替换它们,并且它也不会删除零值。我们也可以先做Counter(b),然后用Counter(a)更新,例子-

>>> y = Counter(b)
>>> y.update(Counter(a))
>>> y
Counter({'b': 6, 'c': 2, 'a': 1, 'd': 0})

您可以继承 Counter 并调整其 __add__ 方法:

from collections import Counter


class MyCounter(Counter):
    def __add__(self, other):
        """Add counts from two counters.
        Preserves counts with zero values.

        >>> MyCounter('abbb') + MyCounter('bcc')
        MyCounter({'b': 4, 'c': 2, 'a': 1})
        >>> MyCounter({'a': 1, 'b': 0}) + MyCounter({'a': 2, 'c': 3})
        MyCounter({'a': 3, 'c': 3, 'b': 0})
        """
        if not isinstance(other, Counter):
            return NotImplemented
        result = MyCounter()
        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


counter1 = MyCounter({'a': 1, 'b': 0})
counter2 = MyCounter({'a': 2, 'c': 3})

print(counter1 + counter2)  # MyCounter({'a': 3, 'c': 3, 'b': 0})

我帮Anand S Kumar做更多的补充说明。

即使您的字典包含负值,它仍会保留您的密钥。

from collections import Counter

a = {"a": 1, "b": 5, "d": -1}
b = {"b": 1, "c": 2}

print Counter(a) + Counter(b)
#Counter({'b': 6, 'c': 2, 'a': 1})

x = Counter(a)
x.update(Counter(b))
print x
#Counter({'b': 6, 'c': 2, 'a': 1, 'd': -1})