nektar
nektar

Reputation: 73

Identifying the values which have the maximum number of keys

I have a dict which goes something like this:

 ip = { "1" : ['a','b'],
      "2" : ['a','c'],
      "3" : ['a','b','c','d'],
      "4" : ['a','b','d','e']}

I need to find which of the items in the value sets have maximum number of keys against them and also have the items listed in descending order. The output will be something like :

op = {"a":4,"b":3,"c":2,"d":2,"e":1}

But I read somewhere that the dict cannot be in a sorted fashion, so the output can be a tuple too:

op = [('a', 4), ('b', 3), ('c', 2), ('d', 2), ('e', 1)]

We can iterate through the dict and for each of the items in the value set increment the result in a defaultdict for that item.

op = defaultdict(int)
for k,v in ip.iteritems():
    for item in v:
        op[item]+=1
op = sorted(op.items(), key=lambda x: x[1], reverse=True)

Is there a quicker/better way of doing this than the nested for?

Upvotes: 5

Views: 81

Answers (2)

Sede
Sede

Reputation: 61253

Simply use Counter and chain.from_iterable

In [9]: from collections import Counter

In [10]: from itertools import chain

In [11]: ip = { "1" : ['a','b'],
    ...:       "2" : ['a','c'],
    ...:       "3" : ['a','b','c','d'],
    ...:       "4" : ['a','b','d','e']}

In [12]: Counter(chain.from_iterable(ip.values()))
Out[12]: Counter({'a': 4, 'b': 3, 'c': 2, 'd': 2, 'e': 1})

To remove duplicate value you can always do something like this:

>>> from operator import itemgetter
>>> sorted(Counter(chain.from_iterable(map(set, ip.values()))).items(), key=itemgetter(1), reverse=True)
[('a', 4), ('b', 3), ('c', 2), ('d', 2), ('e', 1)]

Upvotes: 3

This here is not correct:

sorted(op.items(), key=lambda x: x[1], reverse=True)

Try instead:

sorted(ip, key=lambda elementInDict: len(ip[elementInDict]), reverse=True)

example:

for elementInDict in sorted(ip, key=lambda elementInDict: len(ip[elementInDict]), reverse=True):
    print elementInDict,

Upvotes: 0

Related Questions