0

I'm trying to find a way to count the number of occurrences of letters in a text file than display them in greatest to lowest depending upon there frequency. This is what I have so far, please help get over this brain block.

def me():
    info= input("what file would you like to select?")
    filehandle= open(info,"r")
    data=filehandle.read()
    case = data.upper()
    s=('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
    for i in range(26):
        print(s[i],case.count(s[i]))



me()
CT Zhu
  • 52,648
  • 17
  • 120
  • 133
Corey Quick
  • 1
  • 1
  • 3

5 Answers5

2

Python has a nice built-in class for this: collections.Counter.

In [8]: from collections import Counter

In [9]: with open('Makefile', 'r') as f:
   ...:     raw = Counter(f.read())
   ...:

In [10]: raw
Out[10]: Counter({' ': 61, 'e': 46, 'p': 38, 'a': 29, '\n': 27, 'c': 27, 'n': 27, 'l': 26, 'd': 25, '-': 22, 's': 22, 'y': 22, 't': 20, 'i': 18, 'o': 18, 'r': 17, '.': 16, 'u': 13, '\t': 12, 'm': 12, 'b': 11, 'x': 10, 'h': 9, '/': 8, ':': 8, '_': 7, "'": 6, ';': 5, '\\': 5, 'f': 5, '*': 3, 'v': 3, '{': 3, '}': 3, 'k': 2, 'H': 1, 'O': 1, 'N': 1, 'P': 1, 'Y': 1, 'g': 1})

This is from the pandas library's Makefile, BTW. To sort them by their frequency in descending order, do:

In [22]: raw.most_common()
Out[22]:
[(' ', 61),
 ('e', 46),
 ('p', 38),
 ('a', 29),
 ('\n', 27),
 ('c', 27),
 ('n', 27),
 ('l', 26),
 ('d', 25),
 ('-', 22),
 ('s', 22),
 ('y', 22),
 ('t', 20),
 ('i', 18),
 ('o', 18),
 ('r', 17),
 ('.', 16),
 ('u', 13),
 ('\t', 12),
 ('m', 12),
 ('b', 11),
 ('x', 10),
 ('h', 9),
 ('/', 8),
 (':', 8),
 ('_', 7),
 ("'", 6),
 (';', 5),
 ('\\', 5),
 ('f', 5),
 ('*', 3),
 ('v', 3),
 ('{', 3),
 ('}', 3),
 ('k', 2),
 ('H', 1),
 ('O', 1),
 ('N', 1),
 ('P', 1),
 ('Y', 1),
 ('g', 1)]

I'm purposefully not using your exact data so that you can try and adapt my solution to your problem.

Phillip Cloud
  • 24,919
  • 11
  • 68
  • 88
2

This is exactly what collections.Counter and its most_common() method are for:

import collections
import string

def me():
    info = input("what file would you like to select? ")
    filehandle = open(info, "r")
    data = filehandle.read().upper()
    char_counter = collections.Counter(data)
    for char, count in char_counter.most_common():
        if char in string.ascii_uppercase:
            print(char, count)

me()

A Counter is a dictionary that counts the number of occurrences of different items (in this case, characters). char_counter.most_common() gives us all pairs of characters and counts in sorted order.

We're only interested in letters, so we check if the character is in string.ascii_uppercase. This is simply a string of letters from A to Z.

flornquake
  • 3,156
  • 1
  • 21
  • 32
0

This looks like a homework very very... much. And I wish you are properly using this website. However, glad you come to the right place and I would try to help you out at least this time.

>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> input_txt = "Now you are just somebody that I used to know"
>>> for letter in input_txt:
...     d[letter] += 1
... 
>>> import operator
>>> sorted_d = sorted(d.iteritems(), key=operator.itemgetter(1), reverse=True)
>>> sorted_d
[(' ', 9), ('o', 6), ('t', 4), ('e', 3), ('s', 3), ('u', 3), ('a', 2), ('d', 2), ('w', 2), ('y', 2), ('b', 1), ('I', 1), ('h', 1), ('k', 1), ('j', 1), ('m', 1), ('N', 1), ('r', 1), ('n', 1)]
B.Mr.W.
  • 18,910
  • 35
  • 114
  • 178
0

You could do something along these lines:

d={}
with open('/usr/share/dict/words') as f:
    for line in f:
        for word in line.split():
            word=word.strip()
            for c in word:
                d[c]=d.setdefault(c,0)+1

for k, v in sorted(d.items(), key=lambda t: t[1], reverse=True):
    print k,v 

For the standard Unix words file, prints:

e 234413
i 200536
a 196995
o 170062
r 160269
...
Y 139
X 92
Q 77
- 2            
dawg
  • 98,345
  • 23
  • 131
  • 206
  • `d.most_common()` returns a list of items sort from most common to least. So you can skip the sorting step. – Steven Rumbalski Sep 04 '13 at 01:58
  • @StevenRumbalski: That would only be if you use an instance of `Counter`. A Python base dict does not have a `.most_common()` method. – dawg Sep 04 '13 at 03:01
  • Whoops. I misread your answer to think you had a `Counter`. I think perhaps I read another answer and then accidentally commented on yours. – Steven Rumbalski Sep 05 '13 at 14:10
0

Others have already given you better solutions using itertools.Counter, but your code was close; you just can't print the sorted output on the fly. You could save the counts in a list, sort it and then print:

def me():
    info = input("what file would you like to select?")
    filehandle = open(info,"r")
    data = filehandle.read()
    case = data.upper()
    s = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
    result = []
    for i in range(26):
        result.append((s[i], case.count(s[i])))
    return result

result = me()
for letter, count in sorted(result, key=lambda x: x[1], reverse=True):
    print(letter, count)

Still using your logic, you can make the function more readable:

import string

def me():
    info = input("what file would you like to select?")
    filehandle = open(info,"r")
    data = filehandle.read()
    case = data.upper()
    result = []
    for letter in string.uppercase:
        result.append((letter, case.count(letter)))
    return result
Paulo Almeida
  • 7,803
  • 28
  • 36