Home > Enterprise >  SUM element-wise values of Python dict based on another list
SUM element-wise values of Python dict based on another list

Time:07-17

I have a dictionary and a list

mylist=[('B',), ('D',), ('B', 'D'), ('B', 'J'), ('B', 'P'), ('B', 'M'), ('D', 'J'), ('D', 'P'), ('D', 'M'), ('J', 'P'), ('J', 'M'), ('P', 'M'), ('B', 'D', 'J'), ('B', 'D', 'P'), ('B', 'D', 'M')]

dict={'B': [1, 0, 1, 1], 'D': [1, 1, 0, 1], 'J': [0, 0, 1, 1], 'P': [1, 1, 0, 1], 'M': [1, 0, 0, 1]}

what i was trying to do is to sum up the dictionary value based on the list. My code is:

myresult=[]
for k,v in dict.items():
        row=sum(v for k, v in dict.items() if k in mylist) 
        myresult.append(row)

What i got was [0,0,0,0,0]

The intended result was to sum individual items from dictionary based on mylist and return something like

[(1,0,1,1), (1,1,0,1), (2,1,1,2), xxxx]

Could anyone help ?

CodePudding user response:

mylist=[('B',), ('D',), ('B', 'D'), ('B', 'J'), ('B', 'P'), ('B', 'M'), ('D', 'J'), ('D', 'P'), ('D', 'M'), ('J', 'P'), ('J', 'M'), ('P', 'M'), ('B', 'D', 'J'), ('B', 'D', 'P'), ('B', 'D', 'M')]

# change dict to dict_map
dict_map={'B': [1, 0, 1, 1], 'D': [1, 1, 0, 1], 'J': [0, 0, 1, 1], 'P': [1, 1, 0, 1], 'M': [1, 0, 0, 1]}

myresult = []
for item in mylist:
    arrays = [dict_map.get(i) for i in item]
    sum_list = [sum(x) for x in zip(*arrays)]
    myresult.append(sum_list)
    print(sum_list)
    

result:

[1, 0, 1, 1]
[1, 1, 0, 1]
[2, 1, 1, 2]
[1, 0, 2, 2]
[2, 1, 1, 2]
[2, 0, 1, 2]
[1, 1, 1, 2]
[2, 2, 0, 2]
[2, 1, 0, 2]
[1, 1, 1, 2]
[1, 0, 1, 2]
[2, 1, 0, 2]
[2, 1, 2, 3]
[3, 2, 1, 3]
[3, 1, 1, 3]

CodePudding user response:

One approach using functional programming:

from functools import reduce

my_list = [('B',), ('D',), ('B', 'D'), ('B', 'J'), ('B', 'P'), ('B', 'M'), ('D', 'J'), ('D', 'P'), ('D', 'M'),
           ('J', 'P'), ('J', 'M'), ('P', 'M'), ('B', 'D', 'J'), ('B', 'D', 'P'), ('B', 'D', 'M')]

dic = {'B': [1, 0, 1, 1], 'D': [1, 1, 0, 1], 'J': [0, 0, 1, 1], 'P': [1, 1, 0, 1], 'M': [1, 0, 0, 1]}


def element_wise_sum(l, o):
    return [a   b for a, b in zip(l, o)]


res = [reduce(element_wise_sum, [dic[label] for label in labels]) for labels in my_list]
print(res)

Output

[[1, 0, 1, 1], [1, 1, 0, 1], [2, 1, 1, 2], [1, 0, 2, 2], [2, 1, 1, 2], [2, 0, 1, 2], [1, 1, 1, 2], [2, 2, 0, 2], [2, 1, 0, 2], [1, 1, 1, 2], [1, 0, 1, 2], [2, 1, 0, 2], [2, 1, 2, 3], [3, 2, 1, 3], [3, 1, 1, 3]]

CodePudding user response:

You can use simple for loop to iterate the main list and get keys and sums using list comprehension like this way,

mylist=[('B',), ('D',), ('B', 'D'), ('B', 'J'), ('B', 'P'), ('B', 'M'), ('D', 'J'), ('D', 'P'), ('D', 'M'), ('J', 'P'), ('J', 'M'), ('P', 'M'), ('B', 'D', 'J'), ('B', 'D', 'P'), ('B', 'D', 'M')]

dict={'B': [1, 0, 1, 1], 'D': [1, 1, 0, 1], 'J': [0, 0, 1, 1], 'P': [1, 1, 0, 1], 'M': [1, 0, 0, 1]}

myresult = []
for i in mylist:
    keys = [dict.get(j) for j in i]
    summation = [sum(x) for x in zip(*keys)]
    myresult.append(tuple(summation))
print(myresult)

Sample: https://rextester.com/ANFN30711

CodePudding user response:

Try this: (Changeing dict to dct, because recommended don't use built-in functions as variables (built-in functions))

res = []
for k in mylist:
    res.append(tuple(map(sum, zip(*(dct.get(i, []) for i in k)))))
print(res)       

# As one-line 
# res = [tuple(map(sum, zip(*(dct.get(i, []) for i in k)))) for k in mylist]

[(1, 0, 1, 1), (1, 1, 0, 1), (2, 1, 1, 2), (1, 0, 2, 2), (2, 1, 1, 2), (2, 0, 1, 2), (1, 1, 1, 2), (2, 2, 0, 2), (2, 1, 0, 2), (1, 1, 1, 2), (1, 0, 1, 2), (2, 1, 0, 2), (2, 1, 2, 3), (3, 2, 1, 3), (3, 1, 1, 3)]

Explanation:

# for example for  ('B', 'D', 'M')
# dct.get() -> [1, 0, 1, 1], [1, 1, 0, 1], [1, 0, 0, 1]
>>> list(zip(*[[1, 0, 1, 1], [1, 1, 0, 1], [1, 0, 0, 1]]))
[(1, 1, 1), (0, 1, 0), (1, 0, 0), (1, 1, 1)]

>>> tuple(map(sum, zip(*[[1, 0, 1, 1], [1, 1, 0, 1], [1, 0, 0, 1]])))
(3, 1, 1, 3)
  • Related