11

In Python, I've got a list of items like:

mylist = [a, a, a, a, b, b, b, d, d, d, c, c, e]

And I'd like to output something like:

a (4)
b (3)
d (3)
c (2)
e (1)

How can I output a count and leaderboard of items in a list? I'm not too bothered about efficiency, just any way that works :)

Thanks!

AP257
  • 89,519
  • 86
  • 202
  • 261
  • 1
    what have you tried? there are loads of dupes on SO. Have you at least tried looking for them? – SilentGhost Feb 18 '10 at 18:09
  • Yes I have. Sorry, I might be using the wrong search terms but I couldn't find anything that looked like what I needed. I have been experimenting but haven't got very far... apologies – AP257 Feb 18 '10 at 18:12
  • 2
    dupe: http://stackoverflow.com/questions/2148480/can-pythons-list-comprehensions-ideally-do-the-equivalent-of-count-group/2148555#2148555 – SilentGhost Feb 18 '10 at 18:12
  • Is your listed always sorted? – Mark Byers Feb 18 '10 at 18:14
  • Thanks @SilentGhost. I would never have found that from the search terms I was using! Hopefully this question will be useful to more newbie people searching in future. – AP257 Feb 18 '10 at 18:16
  • 1
    Duplicate of all of these: http://stackoverflow.com/search?q=%5Bpython%5D+frequency+count. Specifically, http://stackoverflow.com/questions/2161752/how-to-count-the-frequency-of-the-elements-in-a-list. Since it's exactly a year ago, and has almost the same sample data, this smells like homework. – S.Lott Feb 18 '10 at 18:41
  • sorry, didn't intend to create a duplicate - I really did search but couldn't find anything on the (newbie) search terms I was using! – AP257 Feb 18 '10 at 18:50

3 Answers3

10

I'm surprised that no one has mentioned collections.Counter. Assuming

import collections
mylist = ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'd', 'd', 'd', 'c', 'c', 'e']

it's just a one liner:

print(collections.Counter(mylist).most_common())

which will print:

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

Note that Counter is a subclass of dict with some useful methods for counting objects. Refer to the documentation for more info.

AXO
  • 8,198
  • 6
  • 62
  • 63
8
from collections import defaultdict

def leaders(xs, top=10):
    counts = defaultdict(int)
    for x in xs:
        counts[x] += 1
    return sorted(counts.items(), reverse=True, key=lambda tup: tup[1])[:top]

So this function uses a defaultdict to count the number of each entry in our list. We then take each pair of the entry and its count and sort it in descending order according to the count. We then take the top number of entries and return that.

So now we can say

>>> xs = list("jkl;fpfmklmcvuioqwerklmwqpmksdvjioh0-45mkofwk903rmiok0fmdfjsd")
>>> print leaders(xs)
[('k', 7), ('m', 7), ('f', 5), ('o', 4), ('0', 3), ('d', 3), ('i', 3), ('j', 3), ('l', 3), ('w', 3)]
Eli Courtwright
  • 186,300
  • 67
  • 213
  • 256
6

A two-liner:

for count, elem in sorted(((mylist.count(e), e) for e in set(mylist)), reverse=True):
    print '%s (%d)' % (elem, count)
Otto Allmendinger
  • 27,448
  • 7
  • 68
  • 79