Использование collection.Counter () с набором запросов Django с отрицательными целыми числами - PullRequest
0 голосов
/ 15 мая 2018

В качестве продолжения этого вопроса, который был решен с помощью Counter(), я столкнулся с новой проблемой, которую, по-видимому, достаточно легко решить - за исключением того, что я не могу заставить ее работать.

Я пытаюсь использовать Counter() для суммирования серии записей dict, которая работает, если сумма является положительным целым числом, НО возвращает пустой элемент, если сумма является отрицательным целым числом. Я смог найти этот ответ, который прямо сейчас объясняет, что Counter() предназначен для подсчета, а не для суммирования, по сути.

Я могу воссоздать пример и заставить его работать, но с набором запросов django, в сочетании с методом Counter(), создается более сложный словарь, который выглядит следующим образом.

totals = {
    'sumthing_a': Counter({'total': 48000}), 
    'sumthing_b': Counter({'total': 39050}), 
    'sumthing_c': Counter({'total': 8950}), 
    'sumthing_d': Counter({'total': 10000}), 
    'sumthing_e': Counter({'total': 17200}), 
    'sumthing_f': Counter({'total': 17750}), 
    'sumthing_g': Counter({'total': 30450}),
    }

Я пробовал варианты:

totals.update({'sumthing_e': Counter({'total': 300})})

, который заменяет исходный 17200 на 300 вместо их добавления.

Я тоже пробовал:

totals['sumthing_e'].update({'sumthing_e': Counter({'total': 300})})

который бросает: unsupported operand type(s) for +: 'Counter' and 'int'

Документация для .update() гласит:

Элементы считаются из итерируемого или добавляемого из другого отображения (или счетчик). Как и в dict.update (), но вместо замены добавляет количество их. Кроме того, итерируемый, как ожидается, будет последовательность элементов, а не последовательность пар (ключ, значение).

И есть документация, в которой говорится:

Для операций на месте, таких как c [key] + = 1, тип значения нужен только Поддержка сложения и вычитания. Таким образом, дроби, числа с плавающей запятой и десятичные дроби будет работать и отрицательные значения поддерживаются. То же самое верно и для update () и subtract (), которые допускают отрицательные и нулевые значения для оба входа и выхода.

Это заставляет меня верить, что то, что я пытаюсь сделать, возможно, если оно правильно закодировано. Конечным результатом должна стать возможность иметь отрицательное число - например:

totals = {
    'sumthing_a': Counter({'total': 48000}), 
    'sumthing_b': Counter({'total': -40503}), 
    'sumthing_c': Counter({'total': 8950}), 
    'sumthing_d': Counter({'total': 10000}), 
    'sumthing_e': Counter({'total': -58462}), 
    'sumthing_f': Counter({'total': 17750}), 
    'sumthing_g': Counter({'total': 30450}),
    }

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Расширение на правильный ответ @ BearBrown:

Исходная словарная запись принимает формат

'sumthing_a': Counter({'total': 48000})

, а .update(Counter()) принимает только словарь счетчиков - эта часть

{'total': 48000}

Поэтому, чтобы извлечь словарь, понадобился следующий код

dict(totals.get('sumthing_a'))

Возвращение затем передается методу .update() в ответе @ BearBrown.

0 голосов
/ 16 мая 2018

посмотрите на тип totals['sumthing_e']

In [13]: type(totals['sumthing_e'])
Out[13]: collections.Counter

и вы пытаетесь обновить его по общему словарю {'sumthing_e': Counter({'total': 300})}

поэтому, если вы хотите сбросить счетчик, как в вашем рабочем примере, вы должны сделать:

totals['sumthing_e'] = Counter({'total': 300})

но если вы хотите обновить свой счетчик, вы должны сделать:

In [15]: totals['sumthing_e'].update(Counter({'total': 300}))

In [16]: totals['sumthing_e']
Out[16]: Counter({'total': 600})

In [17]: totals['sumthing_e'].update(Counter({'total': 300}))

In [18]: totals['sumthing_e']
Out[18]: Counter({'total': 900})

In [19]: totals['sumthing_e'].update(Counter({'total': -200}))

In [20]: totals['sumthing_e']
Out[20]: Counter({'total': 700})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...