collection.Counter, есть ли способ избежать добавления строковых значений? - PullRequest
0 голосов
/ 16 февраля 2020

Например, у меня есть два словаря.

>>> dict_a = {'total': 20, 'remaining': 10, 'group': 'group_a'}
>>> dict_b = {'total': 30, 'remaining': 29, 'group': 'group_a'}

Я использую collection.Counter для целей подсчета.

>>> dict_c = Counter()
>>> dict_c.update(Counter(dict_a))
>>> dict_c.update(Counter(dict_b))
>>> print(dict_c)
{'toal': 50, 'remaining': 39, 'group': 'group_agroup_a'}

Есть ли способ добавить только значения типа integer? т.е. при добавлении он добавляет только значения целочисленного типа.

>>> print(dict_c)
>>> {'toal': 50, 'remaining': 39, 'group': 'group_a'}

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Вы можете определить свою собственную функцию для добавления двух Counter объектов, подобных тем, которые у вас есть в вашем вопросе. Это необходимо, потому что метод по умолчанию для добавления Counter объектов не может обрабатывать нечисловые значения c в них, как вы вводите свои.

from collections import Counter

def add_counters(a, b):
    """ Add numerical counts from two Counters. """
    if not isinstance(a, Counter) or not isinstance(a, Counter):
        return NotImplemented
    result = Counter()
    for elem, count in a.items():
        newcount = count + b[elem]
        try:
            if newcount > 0:
                result[elem] = newcount
        except TypeError:
            result[elem] = count  # Just copy value.

    for elem, count in b.items():
        if elem not in a and count > 0:
            result[elem] = count

    return result


dict_a = {'total': 20, 'remaining': 10, 'group': 'group_a'}
dict_b = {'total': 30, 'remaining': 29, 'group': 'group_a'}
dict_c = add_counters(Counter(dict_a), Counter(dict_b))
print(dict_c)  # -> Counter({'total': 50, 'remaining': 39, 'group': 'group_a'})

Обратите внимание, что вышеупомянутое не может быть совершенно правильно, потому что любые нечисленные c элементы в первом Counter аргументе a, которые только что скопированы в результат, могут быть перезаписаны вторым for l oop, поэтому их окончательное значение будет таким, как во втором Counter с именем b. Это так, потому что вы не определили точно, что вы хотите, чтобы произошло в таком случае.

0 голосов
/ 17 февраля 2020

Есть ли способ добавить только значения целочисленного типа?

Возможно, это не самое эффективное решение, но вы можете просто перебирать пары ключ-значение dict_c проверить, имеют ли значения тип int, чтобы создать новый словарь, содержащий только целочисленные значения.

from collections import Counter

dict_a = {'total': 20, 'remaining': 10, 'group': 'group_a'}
dict_b = {'total': 30, 'remaining': 29, 'group': 'group_a'}
dict_c = Counter(dict_a) + Counter(dict_b)
dict_result = {key: value for key, value in dict_c.items() if isinstance(value, int)}
print(dict_result)

Возвращает ожидаемый результат:

{'total': 50, 'remaining': 39}
...