Question

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}

Was it helpful?

Solution

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).

OTHER TIPS

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}
>>> 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}

Tiny explanation:

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top