Reputation: 10506
If i have this dictionary:
a = {'alpha':12,'beta':13,'gamma':14}
and this one:
b = {'andora':19,'beta:14','gamma':19}
and this one:
c = {'beta':11,'gamma':20}
how do i intersect the keys such that the resultant dictionary would have values as the average of the values in the given dictionaries.
for example:
intersect([a,b,c]) -> {'beta':12.6666666667,'gamma':17.6666666667}
Upvotes: 1
Views: 112
Reputation: 251096
Use a dict comprehension:
>>> keys = a.viewkeys() & b.viewkeys() & c.viewkeys()
>>> keys
set(['beta', 'gamma'])
>>> {k: (a[k]+b[k]+c[k])/3.0 for k in keys}
{'beta': 12.666666666666666, 'gamma': 17.666666666666668}
Function:
>>> def get_keys(*args):
... return reduce(set.intersection,map(set,args))
...
>>> get_keys(a,b,c)
set(['beta', 'gamma'])
intersect
function:
def intersect(dics):
keys = reduce(set.intersection,map(set,dics))
return {k: sum(x[k] for x in dics)/float(len(dics)) for k in keys}
...
>>> intersect([a,b,c])
{'beta': 12.666666666666666, 'gamma': 17.666666666666668}
Upvotes: 1
Reputation: 13410
>>> from operator import and_
>>> from __future__ import division
>>> def intersect(*dicts):
return dict((key,sum(D[key] for D in dicts)/len(dicts)) for key in reduce(and_,map(set,dicts)))
>>> intersect(a,b,c)
{'beta': 12.666666666666666, 'gamma': 17.666666666666668}
and_
is just operator which do the following and_(a,b) === a and b
.
reduce
just apply and
to all the members, so reduce(and_,map(set,dicts)) === a and b and c
, which produces intersection of dictionary keys.
>>> reduce(and_,map(set,dicts))
set(['beta', 'gamma'])
Then we just pass through all those keys and calculate sum of the values from all the dicts corresponding to that key sum(D[key] for D in dicts)
, and divide it by the number of dicts, so we get average for that key, and then get it packed into resultant dictionary via generator expression.
P.S. I wouldn't call this function intersect
. Something like common_key_average
would do better.
Upvotes: 0
Reputation: 208565
def intersect(dicts):
common_keys = reduce(set.intersection, map(set, dicts))
num = float(len(dicts))
return {k: sum(d[k] for d in dicts)/num for k in common_keys}
Example:
>>> a = {'alpha':12,'beta':13,'gamma':14}
>>> b = {'andora':19,'beta':14,'gamma':19}
>>> c = {'beta':11,'gamma':20}
>>> intersect([a, b, c])
{'beta': 12.666666666666666, 'gamma': 17.666666666666668}
If you want to be able to call it like intersect(a, b, c)
instead of needing to wrap them in a list, just change the def
line to def intersect(*dicts)
(the body can stay exactly the same).
Upvotes: 1