74

I have a dictionary like this:

A = {'a':10, 'b':843, 'c': 39,.....}

I want to get the 5 maximum values of this dict and store a new dict with this. To get the maximum value I did:

max(A.iteritems(), key=operator.itemgetter(1))[0:]

Perhaps it is an easy task, but I am stuck on it for a long time. Please help!!!

Alejandro
  • 4,945
  • 6
  • 32
  • 30

5 Answers5

131

No need to use iteritems and itemgetter. The dict's own get method works fine.

max(A, key=A.get)

Similarly for sorting:

sorted(A, key=A.get, reverse=True)[:5]

Finally, if the dict size is unbounded, using a heap will eventually be faster than a full sort.

import heapq
heapq.nlargest(5, A, key=A.get)

For more information, have a look at the heapq documentation.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
A. Coady
  • 54,452
  • 8
  • 34
  • 40
68

You are close. You can sort the list using sorted [docs] and take the first five elements:

newA = dict(sorted(A.iteritems(), key=operator.itemgetter(1), reverse=True)[:5])

See also: Python Sorting HowTo

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 5
    This can be inefficient for a large dictionary, but a more efficient solution is going to be much more complicated. (For example, you could implement a partial Quicksort that doesn't bother to sort both partitions when the higher partition has 5 or more elements.) Most likely the `sorted` technique is good enough for the OP's purposes. – Keith Thompson Aug 25 '11 at 21:26
  • 1
    @keith-thompson thanks for your comment. But how any keys is a "large" dictionary? In my dict, I have like 2000 items, is it large? – Alejandro Aug 25 '11 at 21:55
  • @Alejandro: It's "large" if sorting it causes a significant performance problem. Sort a 2000-item list (of anything) is going to require something on the order of 20,000 comparisons, but if your program produces an answer before your finger leaves the enter key, it's probably not worth optimizing. And the built-in `sorted` operation is likely to be optimized in ways that a hand-written special-purpose algorithm like the one I suggested probably couldn't be. And it's been *very* thoroughly tested. – Keith Thompson Aug 25 '11 at 22:02
  • @Alejandro: Have a look at Coady's answer. I think it is better. – Felix Kling Aug 25 '11 at 22:06
  • I think you're likely to do better with the above suggestion than writing custom code for a top-n algorithm. The above uses built-in Python routines, which might be optimized in C for all I know. That makes its constant factor maybe 20 times better. 20 * n lg 5 > n lg 2000. For 1,000,000 items, maybe handwritten code can be faster, but still I think the solution above will be acceptable and it's not worth the effort to improve it. – morningstar Aug 26 '11 at 00:29
56

You could use collections.Counter here:

dict(Counter(A).most_common(5))

Example:

>>> from collections import Counter
>>> A = {'a' : 1, 'b' : 3, 'c' : 2, 'd' : 4, 'e' : 0, 'f' :5}
>>> dict(Counter(A).most_common(5))
{'a': 1, 'c': 2, 'b': 3, 'd': 4, 'f': 5}
Akavall
  • 82,592
  • 51
  • 207
  • 251
6

For Python 3

import operator
dict(sorted(A.items(), key=operator.itemgetter(1), reverse=True)[:5])
Malinda
  • 336
  • 2
  • 12
4

Try this:

dict(sorted(A.iteritems(), key=operator.itemgetter(1), reverse=True)[:5])
Gerrat
  • 28,863
  • 9
  • 73
  • 101