Counting each letter's frequency in a string - python

This is a question from pyschools.
I did get it right, but I'm guessing that there would be a simpler method. Is this the simplest way to do this?
def countLetters(word):
letterdict={}
for letter in word:
letterdict[letter] = 0
for letter in word:
letterdict[letter] += 1
return letterdict
This should look something like this:
>>> countLetters('google')
{'e': 1, 'g': 2, 'l': 1, 'o': 2}

In 2.7+:
import collections
letters = collections.Counter('google')
Earlier (2.5+, that's ancient by now):
import collections
letters = collections.defaultdict(int)
for letter in word:
letters[letter] += 1

>>> import collections
>>> print collections.Counter("google")
Counter({'o': 2, 'g': 2, 'e': 1, 'l': 1})

Related

How to check whether the letter (value) is in the dictionary?

I hope you are doing well. I'm working on a dictionary program:
strEntry = str(input("Enter a string: ").upper())
strEntry = strEntry.replace(",", "")
strEntry = strEntry.replace(" ", "")
print('')
def freq_finder(strFinder):
dict = {}
for i in strFinder:
keys = dict.keys()
if i in keys:
dict[i] += 1
else:
dict[i] = 1
return dict
newDic = freq_finder(strEntry)
print(newDic)
newLetter = str(input("Choose a letter: ").upper())
if newLetter in newDic.values():
print("Number of occurrence of", message.count(newLetter))
newDic.pop(newLetter)
print("Dictinary after that letter removed:", newDic)
else:
print("Letter not in dictionary")
sortedDic = sorted(newDic)
print(sortedDic)
Everything works fine before this part:
newLetter = str(input("Choose a letter: ").upper())
if newLetter in newDic.values():
print("Number of occurrence of", message.count(newLetter))
newDic.pop(newLetter)
print("Dictinary after that letter removed:", newDic)
else:
print("Letter not in dictionary")
I'm trying to figure out how to check whether the letter is in the dictionary. If it is not, display the message “Letter not in dictionary”. Otherwise, display the frequency count of that letter, remove the letter from the dictionary and display the dictionary after that letter has been removed.
It should look something like this:
Enter a string: Magee, Mississippi
Dictionary: {'M': 2, 'A': 1, 'G': 1, 'E': 2, 'I': 4, 'S': 4, 'P': 2}
Choose a letter: s
Frequency count of that letter: 4
Dictionary after that letter removed: {'M': 2, 'A': 1, 'G': 1, 'E': 2, 'I': 4, 'P': 2}
Letters sorted: ['A', 'E', 'G', 'I', 'M', 'P']
I would highly appreciate it if you could tell me what's wrong and how to fix it.
Check for the keys, not the value (Because the Value is a number, not a letter) -
if newLetter in newDic: # Or if newLetter in list(newDic.keys())
print("Number of occurrence of", message.count(newLetter))
For this - Dictionary: {'M': 2, 'A': 1, 'G': 1, 'E': 2, 'I': 4, 'S': 4, 'P': 2}, you could use Collections.Counter instead

Comparing a string's characters to a dictionary python

Currently working on an assignment and a little stuck. Looking for some assistance to approach this. I'm trying to try a function that takes two values a magazine and a ransom which are input by a user. If the characters in the ransom can be found in the magazine I want to return that it is true otherwise if the ransom string cannot be found in the magazine string return false. ransom is split into a dictionary {key, vaue} so for example the user enters:
Enter magazine: hello there
Enter ransom: hello
{'h': 1, 'e': 1, 'l': 2, 'o': 1}
{'h': 1, 'e': 1, 'l': 1, 'o': 1}
This should return true but it returns false because it does not count the second 'l' in 'hello'. What am I doing wrong?
def compare(magazine, ransom):
matches = {}
for ch in ransom:
if ch in magazine:
if ch in matches:
matches[ch] += 1
else:
matches[ch] = 1
if ransom in matches:
return True
else:
return False
if ransom in matches:
First of all, this comparison seems wrong, ransom is supposed to be a string which is inputted by an user, matches is supposed to be a dictionary.
In your code:
ransom: 'hello'
matches: {'h': 1, 'e': 1, 'l': 2, 'o': 1}
So your if-condition will be like:
if 'hello' in {'h': 1, 'e': 1, 'l': 2, 'o': 1}:
# this line will not be executed
It should be like:
if 'h' in {'h': 1, 'e': 1, 'l': 2, 'o': 1}:
# this line will be executed
A good way to compare this:
# 1. Processing ransom
{'h': 1, 'e': 1, 'l': 2, 'o': 1}
# 2. Processing magazine
{'h': 2, 'e': 3, 'l': 2, 'o': 1}
# 3. Comparing each character and counts of both one by one in a for-loop
ransom is split into a dictionary {key, vaue}
Note: the way of this assumption could be wrong. Dictionary comparison will ignore order of string, and comparing characters counts one by one without order.
# Those examples could give unexpected answers
compare('hello there', 'olleh')
compare('hello there', 'olleeeh')

Merge counter.items() dictionaries into one dictionary

How do I get the output of this code into one dictionary with total number of key:value pairs?
import re
from collections import Counter
splitfirst = open('output.txt', 'r')
input = splitfirst.read()
output = re.split('\n', input)
for line in output:
counter = Counter(line)
ab = counter.items() #gives list of tuples will be converted to dict
abdict = dict(ab)
print abdict
Here is a sample of what I get:
{' ': 393, '-': 5, ',': 1, '.': 1}
{' ': 382, '-': 4, ',': 5, '/': 1, '.': 5, '|': 1, '_': 1, '~': 1}
{' ': 394, '-': 1, ',': 2, '.': 3}
{'!': 1, ' ': 386, 'c': 1, '-': 1, ',': 3, '.': 3, 'v': 1, '=': 1, '\\': 1, '_': 1, '~': 1}
{'!': 3, ' ': 379, 'c': 1, 'e': 1, 'g': 1, ')': 1, 'j': 1, '-': 3, ',': 2, '.': 1, 't': 1, 'z': 2, ']': 1, '\\': 1, '_': 2}
I have 400 of such dictionaries, and Ideally I have to merge them together, but if I understand correctly Counter does not give them all, rather gives them all one after another.
Any help would be appreciated.
The + operator merges counters:
>>> Counter('hello') + Counter('world')
Counter({'l': 3, 'o': 2, 'e': 1, 'r': 1, 'h': 1, 'd': 1, 'w': 1})
so you can use sum to combine a collection of them:
from collections import Counter
with open('output.txt', 'r') as f:
lines = list(f)
counters = [Counter(line) for line in lines]
combined = sum(counters, Counter())
(You also don’t need to use regular expressions to split files into lines; they’re already iterables of lines.)
Here's a mcve of your problem:
import re
from collections import Counter
data = """this is the first line
this is the second one
this is the last one
"""
output = Counter()
for line in re.split('\n', data):
output += Counter(line)
print output
Applying the method in your example you'd get this:
import re
from collections import Counter
with open('output.txt', 'r') as f:
data = f.read()
output = Counter()
for line in re.split('\n', data):
output += Counter(line)
print output

Getting key values from a list of dictionaries

I have a list that contains dictionaries with Letters and Frequencies. Basically, I have 53 dictionaries each for every alphabet (lowercase and uppercase) and space.
adict = {'Letter':'a', 'Frequency':0}
bdict = {'Letter':'b', 'Frequency':0}
cdict = {'Letter':'c', 'Frequency':0}
If you input a word, it will scan the word and update the frequency for its corresponding letter.
for ex in range(0, len(temp)):
if temp[count] == 'a': adict['Frequency']+=1
elif temp[count] == 'b': bdict['Frequency']+=1
elif temp[count] == 'c': cdict['Frequency']+=1
For example, I enter the word "Hello", The letters H,e,l,l,o is detected and its frequencies updated. Non zero frequencies will be transferred to a new list.
if adict['Frequency'] != 0 : newArr.append(adict)
if bdict['Frequency'] != 0 : newArr.append(bdict)
if cdict['Frequency'] != 0 : newArr.append(cdict)
After this, I had the newArr sorted by Frequency and transferred to a new list called finalArr. Below is a sample list contents for the word "Hello"
{'Letter': 'H', 'Frequency': 1}
{'Letter': 'e', 'Frequency': 1}
{'Letter': 'o', 'Frequency': 1}
{'Letter': 'l', 'Frequency': 2}
Now what I want is to transfer only the key values to 2 seperate lists; letterArr and numArr. How do I do this? my desired output is:
letterArr = [H,e,o,l]
numArr = [1,1,1,2]
Why don't you just use a collections.Counter? For example:
from collections import Counter
from operator import itemgetter
word = input('Enter a word: ')
c = Counter(word)
letter_arr, num_arr = zip(*sorted(c.items(), key=itemgetter(1,0)))
print(letter_arr)
print(num_arr)
Note the use of sorted() to sort by increasing frequency. itemgetter() is used to reverse the sort order so that the sort is performed first on the frequency, and then on the letter. The sorted frequencies are then separated using zip() on the unpacked list.
Demo
Enter a word: Hello
('H', 'e', 'o', 'l')
(1, 1, 1, 2)
The results are tuples, but you can convert to lists if you want with list(letter_arr) and list(num_arr).
I have a hard time understanding your data structure choice for this problem.
Why don't you just go with a dictionary like this:
frequencies = { 'H': 1, 'e': 1, 'l': 2, 'o': 1 }
Which is even easier to implement with a Counter:
from collections import Counter
frequencies = Counter("Hello")
print(frequencies)
>>> Counter({ 'H': 1, 'e': 1, 'l': 2, 'o': 1 })
Then to add another word, you'd simply have to use the updatemethod:
frequencies.update("How")
print(frequencies)
>>> Counter({'l': 2, 'H': 2, 'o': 2, 'w': 1, 'e': 1})
Finally, to get your 2 arrays, you can do:
letterArr, numArr = zip(*frequencies.items())
This will give you tuples though, if you really need lists, just do: list(letterArr)
You wanted a simple answer without further todo like zip, collections, itemgetter etc. This does the minimum to get it done, 3 lines in a loop.
finalArr= [{'Letter': 'H', 'Frequency': 1},
{'Letter': 'e', 'Frequency': 1},
{'Letter': 'o', 'Frequency': 1},
{'Letter': 'l', 'Frequency': 2}]
letterArr = []
numArr = []
for i in range(len(finalArr)):
letterArr.append(finalArr[i]['Letter'])
numArr.append(finalArr[i]['Frequency'])
print letterArr
print numArr
Output is
['H', 'e', 'o', 'l']
[1, 1, 1, 2]

Python: Print the common letter from user input

Is there a better way the write this code. While there are no errors it seems that its printing all the letters I typed sorted into a list.
I want to print the common letters in a string, even if more than one.
Here is what I Have
mystr = input("Enter a string:")
s = list(mystr)
letter_counter = {}
for word in mystr:
if word in letter_counter:
letter_counter[word] += 1
else:
letter_counter[word] = 1
user_letter = sorted(letter_counter, key = letter_counter.get, reverse = True)
number_1 = user_letter[:2]
print(number_1)
The only way I can print the correct letters is by setting a limit on
number_1 = user_letter[:2]
For example if I enter the following:
mystr = input("Thomas Jones")
in the code the printed
output would be
print(number_1)
[o], [s]
Which is right but if the limit was set to from 2 to 3
number_1 = user_letter[:3]
It will print [o] [s] [a] there is only one a it shouldn't be there.
I want it so that any amount the of words the user inputs it will show the correct repeated letter without the limiter.
I'm liberality stuck I have no idea how to correct this
from collections import Counter
[letter for letter,count in Counter("Thomas Jones").items() if count > 1]
Your code produces
letter_counter = {'a': 1, ' ': 1, 'e': 1, 'h': 1, 'J': 1, 'm': 1, 'o': 2, 'n': 1, 's': 2, 'T': 1}
user_letter = ['o', 's', 'a', ' ', 'e', 'h', 'J', 'm', 'n', 'T']
which is all correct.
If you only want the repetitive letters, try
user_letter = [letter for letter in letter_counter if letter_counter[letter] > 1]
or something similar.

Categories

Resources