ActiveState Code

Recipe 52231: Count items and sort by incidence


I've often found it necessary to produce ascending or descending counts -- the most or least common words in a file, popular pages on a website, etc. This is a simple class that makes this easy.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Counter:
    def __init__(self):
        self.dict = {}
    def add(self,item):
        count = self.dict.setdefault(item,0)
        self.dict[item] = count + 1
    def counts(self,desc=None):
        '''Returns list of keys, sorted by values.
        Feed a 1 if you want a descending sort.'''
        i = map(lambda t: list(t),self.dict.items())
        map(lambda r: r.reverse(),i)
        i.sort()
        if desc:
            i.reverse()
        return i

if __name__ == '__main__':

    '''Produces:

>>> Ascending count:
[[1, 'but'], [1, 'it'], [1, 'not.'], [1, 'now'], [1, 'test,'], [1, 'test.'], [1, 'was'], [2, 'Hello'], [2, 'a'], [2, 'is'], [2, 'there'], [2, 'this']]
Descending count:
[[2, 'this'], [2, 'there'], [2, 'is'], [2, 'a'], [2, 'Hello'], [1, 'was'], [1, 'test.'], [1, 'test,'], [1, 'now'], [1, 'not.'], [1, 'it'], [1, 'but']]
    '''

    sentence = "Hello there this is a test.  Hello there this was a test, but now it is not."
    words = sentence.split()
    c=Counter()
    for word in words:
        c.add(word)
    print "Ascending count:"
    print c.counts()
    print "Descending count:"
    print c.counts(1)

Discussion

The counts() method is where all the action is. It takes the object's dictionary and produces an ascending or descending sort of keys by values, returning a list.

Comments

  1. 1. At 11:53 a.m. on 13 mar 2001, Fred Bremmer said:

    List comprehension instead of map(). If you use a Python 2 list comprehension instead of the two map() calls, the code is a little easier to read:

    def counts(self,desc=None):
        result = [[val, key] for (key, val) in self.dict.items()]
        result.sort()
        if desc: result.reverse()
        return result
    

    PS. It would be cool to have a link to download each Cookbook code snippet instead of having to copy, paste and then fix the whitespace. Fred Bremmer

  2. 2. At 9:13 a.m. on 5 apr 2001, andy mckay said:

    Text Source available. Now you can by clicking on "Text Source"

Sign in to comment