-1

I have a dict as below:

dict_data = {
  "NAME": ['A', 'B', 'A', 'B', 'C', 'C'],
  "VALUE": [100, 200 , 100 , 200, 300, 300]
}

How to sum values from above dict if NAME duplicate output:

NAME: A
VALUE: 200
NAME: B
VALUE: 400
NAME: C
VALUE: 600

or output to with list:

[A, B, C]
[200, 400, 600]

i using as below:

data = dict.fromkeys(dict_data['NAME'], 0) #create a new dict from value "NAME" of DICT_DATA
for NAME, VALUE in zip(dict_data['NAME'], dict_data['VALUE']):
  data[NAME] += value # Dict NAME A + Dict Name A,... similar to B and C
for key,value in data.items():
 print(list(key))
 print(list(value))
Đặng Lực
  • 54
  • 1
  • 8

3 Answers3

2

Use a collections.defaultdict then iterate and sum by grouping on key

dict_data = {"NAME": ["A", "B", "A", "B", "C", "C"], "VALUE": [100, 200, 100, 200, 300, 300]}
from collections import defaultdict

result = defaultdict(int)
for key, value in zip(dict_data['NAME'], dict_data['VALUE']):
    result[key] += value
for key, value in result.items():
    print("NAME", key)
    print("VALUE", value)

keys, values = zip(*result.items())
print(keys)
print(values)
NAME A
VALUE 200
NAME B
VALUE 400
NAME C
VALUE 600

('A', 'B', 'C')
(200, 400, 600)
azro
  • 53,056
  • 7
  • 34
  • 70
2

You can use defaultdict with zero in start.

dict_data = {
  "NAME": ['A', 'B', 'A' , 'B' , 'C' , 'C'],
  "VALUE": [100, 200 , 100 , 200, 300, 300]
}

from collections import defaultdict

# res = defaultdict(lambda : 0)
res = defaultdict(int)

for k,v in zip(dict_data['NAME'], dict_data['VALUE']):
    res[k] += v
    
print(list(res.keys()))
print(list(res.values()))

Output:

['A', 'B', 'C']
[200, 400, 600]
I'mahdi
  • 23,382
  • 5
  • 22
  • 30
  • 1
    Hi I'mahdi, what "lambda : 0" mean ? If value not 100 , 200 , 300 instead 1234, 1234 , 2345 ,2345 ? i think lambda : 0 not correct – Đặng Lực Jul 13 '22 at 15:14
  • @ĐặngLực `lambda: 0` is just a function that always returns 0. It is used for the first time a key is accessed. It is equivalent to `int` – Tomerikoo Jul 13 '22 at 15:16
  • @ĐặngLực, You can create `dict` and set what is type of elements like : `defaultdict(list)` or `defaultdict(int)` or `defaultdict(lambda : 0)`. If you don't use defualtdict, you can not wtite `res[k] += v` but when use `defaultdict`, you can suppose you have key and add value to `zero`. – I'mahdi Jul 13 '22 at 15:16
  • 1
    @ĐặngLực, You can start from `10` instead of `zero` with : `defaultdict(lambda : 10)` – I'mahdi Jul 13 '22 at 15:20
  • Hi @I'mahdi, if i have add one more row on dict_data "NAME2": ['W', 'T', 'W', 'T', 'Y', 'Y']. Can i use defaultdict ? OUTPUT: ``` [A, B, C] [200, 400, 600] [W,T,Y] ``` – Đặng Lực Jul 13 '22 at 15:45
  • @ĐặngLực, with `NAME2` -> what is desired output? – I'mahdi Jul 13 '22 at 15:46
  • @I'mahdi output `[A, B, C] [200, 400, 600] [W,T,Y]` – Đặng Lực Jul 13 '22 at 15:47
  • @ĐặngLực, check duplicated on `NAME1`? – I'mahdi Jul 13 '22 at 15:49
  • @I'mahdi Yes, Check duplicated on `NAME1` – Đặng Lực Jul 13 '22 at 15:52
  • 1
    try this: ```dict_data = { "NAME": ['A', 'B', 'A' , 'B' , 'C' , 'C'], "VALUE": [100, 200 , 100 , 200, 300, 300], "NAME2": ['W', 'T', 'W', 'T', 'Y', 'Y'] } from collections import defaultdict res = defaultdict(int) res2 = {} for a,b,c in zip(dict_data['NAME'], dict_data['VALUE'], dict_data['NAME2']): res[a] += b res2[a] = c print(list(res.keys())) print(list(res.values())) print(list(res2.values()))``` – I'mahdi Jul 13 '22 at 15:54
2

Without extra imports.

Use class method fromkeys to set default values

d = dict.fromkeys(dict_data['NAME'], 0)
for k, v in zip(dict_data['NAME'], dict_data['VALUE']):
    d[k] += v

print(d)

or, more verbosely, with the instance method setdefault

d = {}
for k, v in zip(dict_data['NAME'], dict_data['VALUE']):
    d.setdefault(k, 0)
    d[k] += v

These solutions are meant to reply to the comment "If you don't use defualtdict, you can not wtite res[k] += v"

cards
  • 3,936
  • 1
  • 7
  • 25