Rogue
Rogue

Reputation: 45

Count how many times a list of characters appear in a string - Python (no count or counter)

I'm a Python newbie, taking a class. I have to find out how many times each letter appears in a string. I've seen all the responses about .count and counter, but this has not been covered yet. I took my string and created a list of the characters so they only appeared once. Then I tried to count how many times the character from the list appears in the string, and I just can't get it to work. I know how to check for a specific letter, but I can't make it check for each letter in my list. Program is below (there are some extra codes, but I'm using them to make sure it's counting properly).

# CONSTANTS and Blank Lists
letter_list = []
count = 0
letter_count = []
index = 0

# Begin programming
my_string = 'SUKI IS SWEET'

for ch in my_string:
    if ch not in letter_list:
        letter_list.append(ch)
print(letter_list)
print()

for ch in my_string:
    if letter_list[index] == ch:
        count = count + 1
letter_count.append(count)

# Double-checks to make sure running properly        
print(letter_list[0],'appears',letter_count[0], 'times')
print()
print(letter_count)
print()

When I run this, I get the proper answer: ['S', 'U', 'K', 'I', ' ', 'W', 'E', 'T'] (my letter_list) S appears 3 times (S does appear 3 times) [3] (my letter_count)

However, I KNOW that my letter_count.append is in the wrong place. But if I move it in, it gets jacked up. And the moment I try to move it along by increasing the index, it blows up (see below):

# CONSTANTS and Blank Lists
letter_list = []
count = 0
letter_count = []
index = 0

# Begin programming
my_string = 'SUKI IS SWEET'

for ch in my_string:
    if ch not in letter_list:
        letter_list.append(ch)
print(letter_list)
print()

for ch in my_string:
    if letter_list[index] == ch:
        count = count + 1
    letter_count.append(count)
    index = index + 1

# Double-checks to make sure running properly        
print(letter_list[0],'appears',letter_count[0], 'times')
print()
print(letter_count)
print()

RESULTS: Traceback (most recent call last): File "C:\Users\Rogue\Desktop\TEST_2.py", line 30, in main() File "C:\Users\Rogue\Desktop\TEST_2.py", line 18, in main if letter_list[index] == ch: IndexError: list index out of range

I know I'm messing this up bad. But no matter what I do, I can't seem to get this to work. Please help!

Upvotes: 2

Views: 5448

Answers (5)

Isaac Keleher
Isaac Keleher

Reputation: 83

Building on Ajax1234's top voted answer with a bit more information for less advanced programmers.

A python string is an array. Unlike other languages it is not an array of char type values as Python does not have a char data type. A single letter is simply a string of length 1.

So we can access any 'character' in the string the same as we would any array

my_string = "Hello, World!"
print(my_string[0]
print(my_string[1]
print(my_string[2]

Will print

H
e
l

We can also iterate over it as we would any array

for s in my_string:
    print(s)

So what you want to do here is

my_dict = {} # create your dict

my_string = "HELLO"

# iterate over your string and add to the count in your dict/map
for s in my_string:
   # account for duplicate values!
   if s in my_dict: 
       my_dict[s] += 1
   else:
       my_dict[s] = 1

print(my_dict)

So if you enter hello as input this will give

{'h': 1, 'e': 1, 'l': 2, 'o': 1}

Since you are counting letters rather than unique characters you may also want to add an if case and use the lower() inbuilt method.

Upvotes: 0

RoadRunner
RoadRunner

Reputation: 26315

The main issue is that index is incrementing much larger than the actual size of letter_list, which is causing your index error. You need to instead make sure that your letter_list and letter_count lists are parallel and the same length, otherwise too many access errors could occur.

Here is another way of writing this code:

def count_frequency(text):
    letters = []
    freqs = []

    ordered_list = sorted(text)

    for letter in ordered_list:
        if letter not in letters:
            letters.append(letter)
            freqs.append(1)
        else:
            letter_loc = letters.index(letter)
            freqs[letter_loc] += 1

    return letters, freqs

Which uses the same method of having parallel lists keeping track of the letters and their respective frequencies. It sorts the list beforehand using sorted, and returns a tuple containing the letters and frequences.

You can then just print this nicely using zip, which allows you to loop over two same sized lists at once:

letter_freqs = count_frequency('SUKI IS SWEET')

for letter, freq in zip(letter_freqs[0], letter_freqs[1]):
    print(letter, "appears", freq, "times")

Output:

  appears 2 times
E appears 2 times
I appears 2 times
K appears 1 times
S appears 3 times
T appears 1 times
U appears 1 times
W appears 1 times

You will find that this sort of task is much easier with dictionaries and Counters in the future.

Upvotes: 1

PM 2Ring
PM 2Ring

Reputation: 55479

There is a very simple way to do this if you are allowed to use Python's built-in sorted function.

We make a sorted list of the characters from the string, and then we scan the list, looking for places where the character changes. When we find a change, the previous group has ended, so we print its character and its count.

At the start of the loop we have a fake group consisting of the empty string, so we need to skip the printing step for that fake group. At the end of the loop we print the info for the last group.

my_string = 'SUKI IS SWEET'
last, count = '', 0
for c in sorted(my_string):
    if c != last != '':
        print(last, count)
        count = 0
    last = c
    count += 1
print(last, count)

output

  2
E 2
I 2
K 1
S 3
T 1
U 1
W 1

Upvotes: 1

Eric Duminil
Eric Duminil

Reputation: 54233

The index out of range error comes from the fact that index is a large as your original string (13 chars), but you use it on letter_list, which is a large as the number of unique characters (8 unique chars).

Here's a modified version of your code. It's not efficient, but it works and doesn't require dicts or Counters:

letter_list = []
letter_count = []

# Begin programming
my_string = 'SUKI IS SWEET'

# Create a list of unique characters
for ch in my_string:
    if ch not in letter_list:
        letter_list.append(ch)
        letter_count.append(0)

# Increment values in letter_count
for ch in my_string:
    for index in range(len(letter_list)):
        if letter_list[index] == ch:
            letter_count[index] += 1

# Double-checks to make sure running properly     
print(letter_list)
print(letter_count)

for index in range(len(letter_list)):
    print("'" + letter_list[index] + "'",'appears',letter_count[index], 'times')

It outputs:

['S', 'U', 'K', 'I', ' ', 'W', 'E', 'T']
[3, 1, 1, 2, 2, 1, 2, 1]

'S' appears 3 times
'U' appears 1 times
'K' appears 1 times
'I' appears 2 times
' ' appears 2 times
'W' appears 1 times
'E' appears 2 times
'T' appears 1 times

Upvotes: 2

Ajax1234
Ajax1234

Reputation: 71451

You can use a dictionary:

count = {}
my_string = 'SUKI IS SWEET'
for i in my_string:
   if i in count: #check if it exists in dictionary
      count[i] += 1
   else:
      count[i] = 1 #first occurrence of character

print(count)

Output:

{' ': 2, 'E': 2, 'I': 2, 'K': 1, 'S': 3, 'U': 1, 'T': 1, 'W': 1}

Upvotes: 3

Related Questions