-3

Looking at the class below I need to write a code to define "character frequency" so it returns something like the examples below.

class EnhancedString:
    def __init__(self, contents):
        self._contents = str(contents)
    def __str__(self):
        return str(self._contents)
    def __len__(self):
        return len(self._contents)
    def set_contents(self, contents):
        self._contents = str(contents)
    def get_contents(self):
        return self._contents
    **def character_frequency(self):**
 
"""
        Returns a dictionary containing all characters found in _contents as keys, with integer values corresponding to the number of occurrences of each character. Use a while loop to traverse _contents.
        :return: A dictionary with characters as keys and integers as values
        Example use:
            >>> c = EnhancedString("")
            >>> print(c.character_frequency())
            {}
            >>> a = EnhancedString("abcdefg")
            >>> print(a.character_frequency())
            {'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'f': 1, 'g': 1} >>> b = EnhancedString("aabcdefgaa")
            >>> print(b.character_frequency())
            {'a': 4, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'f': 1, 'g': 1} """
Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
Jen Diehl
  • 1
  • 2

2 Answers2

1

collections.Counter will count hashable items in a collection, in your case, individual characters in the string.

import collections

class EnhancedString:
    def __init__(self, contents):
        self._contents = str(contents)
    def __str__(self):
        return str(self._contents)
    def __len__(self):
        return len(self._contents)
    def set_contents(self, contents):
        self._contents = str(contents)
    def get_contents(self):
        return self._contents
    def character_frequency(self):
        return collections.Counter(self._contents)

s = EnhancedString("I am the very model of a modern major general")
print(s.character_frequency())

if you want to do this without any extra modules, you can create your own dictionary and add to it.

    def character_frequency(self):
        counts = {}
        for c in self._contents:
            if c not in counts:
                counts[c] = 1
            else:
                counts[c] += 1
        return counts

Or use an exception block

    def character_frequency(self):
        counts = {}
        for c in self._contents:
            try:
                counts[c] += 1
            except KeyError:
                counts[c] = 1
        return counts

A "while" loop is messier. No need to index a collection when you can iterate with a "for".

    def character_frequency(self):
        counts = {}
        i = 0
        end = len(self._contents)
        while i < end:
            c = self._contents[i]
            try:
                counts[c] += 1
            except KeyError:
                counts[c] = 1
            i += 1
        return counts
tdelaney
  • 73,364
  • 6
  • 83
  • 116
0

It's the wrong tool for the job but if you need to do it using a while statement and you want your code to be somewhat Pythonic, you could use an iterator:

content   = "hello world"
counts    = dict.fromkeys(content,0)  # initialize all character counts to zero
iContent  = iter(content)             # iterator on characters
while True:                           # dummy loop, why not at this point ;)
    try: counts[next(iContent)] += 1  # count characters
    except StopIteration: break       # stop when all characters counted

print(counts)
{'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1} 
Alain T.
  • 40,517
  • 4
  • 31
  • 51