0

I have a dictionary like below:

d = [{152: 1}, {151: 3}, {152: 4}, {153: 5}, {153: 10}, {154: -0.1}]

I want to sort them like below:

{151: 3, 152: 5, 153: 15, 154: -0.1}

I tried the below by following this answer ...

sorted = dict(functools.reduce(operator.add, map(collections.Counter, d)))

The output I got is :

{151: 3, 152: 5, 153: 15}

I do not understand why functools.reduce(operator.add, ) removes the {154: -0.1}. Isn't operator.add just a plain summation method?

operator.add(a, b)
operator.add(a, b)
Return a + b, for a and b numbers.

Questions

  • What could be the workaround to achieve the desired output?
  • Why does functools.reduce(operator.add, ) remove the negative value?
koyamashinji
  • 535
  • 1
  • 6
  • 19

3 Answers3

1

The Counter class is designed for positive counts so -0.1 is treated as 0 by its addition method (as would any other negative result). You could do this using a loop and a regular dictionary (no library needed):

dicts = [{152: 1}, {151: 3}, {152: 4}, {153: 5}, {153: 10}, {154: -0.1}]

r = dict()
for d in dicts:
    r.update({k:r.get(k,0)+v for k,v in d.items()})

print(r)
{152: 5, 151: 3, 153: 15, 154: -0.1}

The documentation for Counter states that Each operation can accept inputs with signed counts, but the output will exclude results with counts of zero or less

Alain T.
  • 40,517
  • 4
  • 31
  • 51
  • And to clarify from OP's question: "Why does functools.reduce(operator.add, ) remove the negative value?" It's not that functools.reduce(operator.add, ...) "removes" the negative value; rather, when one Counter object is added to another Counter object (in this case via `functools.reduce`), the resulting Counter object will not contain any key, value pairs where the value would be less than or equal to 0. – Farhaan S. Dec 05 '21 at 14:42
0

A pandas solution

>>>import pandas as pd
>>>d = [{152: 1}, {151: 3}, {152: 4}, {153: 5}, {153: 10}, {154: -0.1}]
>>>pd.DataFrame(d).sum().to_dict()
{152: 5.0, 151: 3.0, 153: 15.0, 154: -0.1}
hpchavaz
  • 1,368
  • 10
  • 16
0

operator.add is a plain summation method, please see its source code: operator.add


Why does functools.reduce(operator.add, ) remove the negative value?

Your one-line code is equivalent to Counter({152: 1}) + Counter({151: 3}) + Counter({152: 4}) + Counter({153: 5}) + Counter({153: 10}) + Counter({154: -0.1})

However, the add method for Counter will remove negative values, check its source: counter-add

Thus, the value for key 154 will be ignored.


How to make your work done?

t = {}
for i in d:
    for k in i.keys():
        t[k] = t[k]+i[k] if k in t else i[k]
Xiang
  • 489
  • 5
  • 11