I have a python dict with the following values
d = {
"k1": [[0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 0, 0]],
"k2": [[0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1]],
"k3": [[0, 1, 0, 1, 0, 1, 0], [1, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1]],
"k4": [[0, 1, 0, 1, 0, 1, 0], [1, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1],[0, 1, 1, 1, 1, 1, 1]]
}
I need to apply a reduce/roll up function on this.
For k1, I am expecting the value as ((1,0,0) (0,1,1) (0,0,1) (0,1,0) (0,0,1) (1,0,0) -> 1 1 1 1 1 1 =6) and so on), k2 as 4 and for k3, it is 7.
For e.g. for k1, I can calculate using this
k1_sum = sum([x | y | z for x,y,z in zip([0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 0, 0])])
k2_sum = sum([x | y for x,y in zip([0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1])])
How do I dynamically unpack the values. There could be several values for each key. It is not fixed. There can be numerous keys.
I would like to write a function and by passing each key, I would like to get the rolled up value.
CodePudding user response:
functools.reduce
is perfect for the job:
from operator import or_
from functools import reduce
d = {
"k1": [[0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1], [0, 1, 1, 0, 1, 0, 0]],
"k2": [[0, 1, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1]],
"k3": [[0, 1, 0, 1, 0, 1, 0], [1, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1]],
"k4": [[0, 1, 0, 1, 0, 1, 0], [1, 1, 1, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1, 1]]
}
sums = {key: sum(reduce(or_, t) for t in zip(*xss)) for key, xss in d.items()}
print(sums)
Result:
{'k1': 6, 'k2': 4, 'k3': 7, 'k4': 7}
Don't use heavier libraries than you need to (like numpy), unless you're using them anyway or you find they give you a performance advantage you need.