count the frequency of each character using the dictionary in python - python-3.x

My program that takes a string as an input from the user and counts the frequency of each character using the dictionary.
Input:
Python programming is fun
Expected output:
{'p': 2, 'y': 1, 't': 1, 'h': 1, 'o': 2, 'n': 3, 'r': 2, 'g': 2, 'a': 1, 'm': 2, 'i': 2, 's': 1, 'f': 1, 'u': 1}
My code:
string = input().lower()
dicx = {}
count = 0
for i in string:
dicx['i'] = ''
print(dicx)

Use collections.Counter
dicx = collections.Counter(string.lower())

You can iterate over string and update the dictionary accordingly and also there's no need of any count variable.
test_str = input().lower()
dicx = {}
for i in test_str:
if i in dicx:
dicx[i] += 1
else:
dicx[i] = 1
print(dicx)

Function takes input as string and counts the character and stores them in a dictionary
from typing import Dict
char_dict = {} #type: Dict[str, int]
def char_count(string: str) -> dict:
new_string = string.lower()
for c in new_string:
if c in char_dict:
char_dict[c] += 1
else:
char_dict[c] = 1
return char_dict
if __name__ == "__main__":
UserString = input("Enter Input String: ")
CharCount = char_count(UserString)
print("Characters Count: ", CharCount)
Example:
Enter Input String: Python programming is fun
Characters Count: {'p': 2, 'y': 1, 't': 1, 'h': 1, 'o': 2, 'n': 3, ' ': 3, 'r': 2, 'g': 2, 'a': 1, 'm': 2, 'i': 2, 's': 1, 'f': 1, 'u': 1}

Way 1: For
symbols = {}
for s in inp_str.lower():
if s in symbols:
symbols[s] += 1
else:
symbols.update({s: 1})
print(symbols)
Way 2: defaultdict
symbols = defaultdict(int)
for s in inp_str.lower():
symbols[s] += 1
print(symbols)
Way 3: Counter
symbols = Counter(inp_str.lower())
print(symbols)

def charCounter(string):
empty = {}
for i in string.lower():
if i in empty.keys():
empty[i] += 1
else:
empty[i] = 1
return empty
print(charCounter("Oh, it is python"))

d = {}
test_str = input().lower()
for x in test_str:
d[x] = d.get(x,0) + 1
print(d)
much more elegant like this

Related

Full addresses from nested dictionaries

We have data like this
input = {
'a': 3,
'b': {'g': {'l': 12}},
'c': {
'q': 3,
'w': {'v': 3},
'r': 8,
'g': 4
},
'd': 4
}
It is not known in advance how many nesting levels there will be
We need to get the full address to the final value, all points of which are separated by a dot, or another special character
Like this:
a:3
b.g.l: 12
c.q: 3
c.w.v: 3
etc
I tried to solve this problem with a recursive function.
def recursive_parse(data: dict, cache: Optional[list]=None):
if cache is None:
cache = []
for k in data:
cache.append(k)
if not isinstance(data[k], dict):
print(f"{'.'.join(cache) } :{data[k]}")
cache.clear()
else:
recursive_parse(data[k], cache)
But I have problems with "remembering" the previous key of the nested dictionary.
a :3
b.g.l :12
c.q :3
w.v :3
r :8
g :4
d :4
What is the correct algorithm to solve this?
It's probably better to use an explicit stack for this, rather than the Python call stack. Recursion is slow in Python, due to high function call overhead, and the recursion limit is fairly conservative.
def dotted(data):
result = {}
stack = list(data.items())
while stack:
k0, v0 = stack.pop()
if isinstance(v0, dict):
for k1, v1 in v0.items():
item = ".".join([k0, k1]), v1
stack.append(item)
else:
result[k0] = v0
return result
Demo:
>>> data
{'a': 3,
'b': {'g': {'l': 12}},
'c': {'q': 3, 'w': {'v': 3}, 'r': 8, 'g': 4},
'd': 4}
>>> for k, v in reversed(dotted(data).items()):
... print(k, v)
...
a 3
b.g.l 12
c.q 3
c.w.v 3
c.r 8
c.g 4
d 4
Try:
dct = {
"a": 3,
"b": {"g": {"l": 12}},
"c": {"q": 3, "w": {"v": 3}, "r": 8, "g": 4},
"d": 4,
}
def parse(d, path=None):
if path is None:
path = []
if isinstance(d, dict):
for k, v in d.items():
yield from parse(v, path + [k])
else:
yield "{}: {}".format(".".join(path), d)
for p in parse(dct):
print(p)
Prints:
a: 3
b.g.l: 12
c.q: 3
c.w.v: 3
c.r: 8
c.g: 4
d: 4

How can I improve this algorithm to count the frequency of characters in a string?

In order to sort in a descending manner, the frequency of char appearance in a string, I've developed the following algorithm.
First I pass the string to a dictionary using each char as a key along with its frequency of appearance as value. Afterwards I have converted the dictionary to a descending sorted multi-dimension list.
I'd like to know how to improve the algorithm, was it a good approach? Can it be done diferently? All proposals are welcome.
#Libraries
from operator import itemgetter
# START
# Function
# String to Dict. Value as freq.
# of appearance and char as key.
def frequencyChar(string):
#string = string.lower() # Optional
freq = 0
thisDict = {}
for char in string:
if char.isalpha(): # just chars
freq = string.count(char)
thisDict[char] = freq # {key:value}
return(thisDict)
str2Dict = frequencyChar("Would you like to travel with me?")
#print(str2Dict)
# Dictionary to list
list_key_value = [[k,v] for k, v in str2Dict.items()]
# Descending sorted list
list_key_value = sorted(list_key_value, key=itemgetter(1), reverse=True)
print("\n", list_key_value, "\n")
#END
You're doing way too much work. collections.Counter counts things for you automatically, and even sorts by frequency:
from collections import Counter
s = "Would you like to travel with me?"
freq = Counter(s)
# Counter({' ': 6, 'o': 3, 'l': 3, 'e': 3, 't': 3, 'u': 2, 'i': 2, 'W': 1, 'd': 1, 'y': 1, 'k': 1, 'r': 1, 'a': 1, 'v': 1, 'w': 1, 'h': 1, 'm': 1, '?': 1})
If you want to remove the spaces from the count:
del freq[' ']
# Counter({'o': 3, 'l': 3, 'e': 3, 't': 3, 'u': 2, 'i': 2, 'W': 1, 'd': 1, 'y': 1, 'k': 1, 'r': 1, 'a': 1, 'v': 1, 'w': 1, 'h': 1, 'm': 1, '?': 1})
Also just in general, your algorithm is doing too much work. string.count involves iterating over the whole string for each character you're trying to count. Instead, you can just iterate once over the whole string, and for every letter you just keep incrementing the key associated with that letter (initialize it to 1 if it's a letter you haven't seen before). That's essentially what Counter is doing for you.
Spelling it out:
count = {}
for letter in the_string:
if not letter.isalpha():
continue
if letter not in count:
count[letter] = 1
else:
count[letter] += 1
And then to sort it you don't need to convert to a list first, you can just do it directly:
ordered = sorted(count.items(), key=itemgetter(1), reverse=True)

How to hash a word using Hashing technique in python using list / dictionary(as c++ )?

I want to hash a word in python to count each letter occurence.
c++ code:
int *arr = new int[256]();
for(int i=0;i<s.size();i++){
arr[s[i]]++;
}
I want to implement the same in python using dictionary or list.
You can use a Counter, after first splitting the string into a list:
from collections import Counter
s = 'hello world'
c = Counter(list(s))
print(c)
Output
Counter({'l': 3, 'o': 2, 'h': 1, ' ': 1, 'd': 1, 'r': 1, 'w': 1, 'e': 1})
s=[3,4,5,4,5]
dict1={}
for i in range(len(s)):
if(s[i] in dict1.keys()):
dict1[s[i]]=dict1[s[i]]+1
else:
dict1[s[i]]=0
print(dict1)
output
{3: 0, 4: 1, 5: 1}
Hope this will answer your question
By using Dictionaries
hsh={}
for i in s:
if i in hsh:
hsh[i]+=1
else:
hsh[i]=1

counting letter frequency with a dict

I'm trying to find the frequency of letters without the Counter.And the code will output a dictionary form of result. And what I have done so far is to make the program count the word frequencies but not the letter/character frequencies. If anyone could point out my mistakes in this code that would be wonderful. Thank you.
It supposed to look like this:
{'a':2,'b':1,'c':1,'d':1,'z':1}
**but this is what I am actually getting:
{'abc':1,'az':1,'ed':1}
**my code is below
word_list=['abc','az','ed']
def count_letter_frequency(word_list):
letter_frequency={}
for word in word_list:
keys=letter_frequency.keys()
if word in keys:
letter_frequency[word]+=1
else:
letter_frequency[word]=1
return letter_frequency
Use collections.Counter
from collections import Counter
print Counter(''.join(word_list))
# Counter({'a': 2, 'c': 1, 'b': 1, 'e': 1, 'd': 1, 'z': 1})
Or count the elements yourself if you don't want to use Counter.
from collections import defaultdict
d = defaultdict(int)
for c in ''.join(word_list):
d[c] += 1
print d
# defaultdict(<type 'int'>, {'a': 2, 'c': 1, 'b': 1, 'e': 1, 'd': 1, 'z': 1})
This is the correct code:
word_list=['abc','az','ed']
def count_letter_frequency(word_list):
letter_frequency={}
for word in word_list:
for letter in word:
keys=letter_frequency.keys()
if letter in keys:
letter_frequency[letter]+=1
else:
letter_frequency[letter]=1
return letter_frequency
You were iterating over the list and the list contains words. So, you were making words as keys in your dictionary. So, you have to add another for loop to iterate over the letters in each word.
Would this be acceptable:
flat = ''.join(word_list)
{l: flat.count(l) for l in set(flat)}
#{'a': 2, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'z': 1}
If you would prefer this in for loop, here it goes:
flat = ''.join(word_list)
result = {}
for l in flat:
if l in result:
result[l] += 1
else:
result[l] = 1

counting letters (only letters) in a long string (python 2.72)

i need to write a function which receives a long string, and puts into a dictionary
each letter, and it's it's appearance frequency in the string.
iv'e written the next function, but the problem it doesn't ignore whitespaces, numbers etc..
iv'e been asked to use the function symbol in string.ascii_lowercase, but iv'e no idea how to do it.
this is my code:
def calc_freq(txt):
dic={}
for letter in range(len(txt)):
if dic.has_key(txt[letter])==True:
dic[txt[letter]] += 1
else:
dic[txt[letter]] = 1
return dic
thanks for any help.
just for fun:
s = 'Type "help", "copyright", "credits" or "license" for more information.'
print dict(filter(lambda i: str.isalnum(i[0]), set(zip(a,map(a.count,a)))))
{'a': 1, 'c': 3, 'e': 6, 'd': 1, 'g': 1, 'f': 2, 'i': 5, 'h': 2, 'm':
2, 'l': 2, 'o': 6, 'n': 3, 'p': 3, 's': 2, 'r': 6, 't': 3, 'y': 2,
'T': 1}
import string
s = 'oasndoasndoansdakls'
count = []
dictionary = {}
for x in set(s):
if x in string.ascii_lowercase:
dictionary[x] = s.count(x)
print (dictionary)
this will create a dictionary of the charactors and their counts, and only include them if they are in the string.ascii_lowercase list.
Here is how to use it in your code:
import string
def calc_freq(txt):
dic={}
for letter in txt:
if letter in string.ascii_lowercase:
if letter in dic:
dic[letter] += 1
else:
dic[letter] = 1
return dic
you just needed to add an if statment before you add the letter to the dictionary or increase its count.
I also removed the letter in range(txt) and txt[letter], you can access each charactor directly in python, because a string is an iterable and can be treated similar to a list.

Resources