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
Related
sem1_credit = {'A': 4, 'B': 4, 'C': 3}
sem2_credit = {'D': 5, 'E': 1}
sem3_credit = {'F': 3}
e = 2
for j in range(e):
for i in 'sem'+str(j+1)+'_credit':
I wanted to use loop to access different dict. So I tried to create the dict name with concatenation using loop. But it doesn't work. Is there a way to work it out or is there some other way to approach dict without loops.
You can get a dictionary of the current local symbols table by calling locals(). So locals()['sem1_credit'] is essentially this sem1_credit.
From here, you can build a loop:
sem1_credit = {'A': 4, 'B': 4, 'C': 3}
sem2_credit = {'D': 5, 'E': 1}
sem3_credit = {'F': 3}
for idx in range(1, 4):
credits = locals()[f'sem{idx}_credit']
for key, credit in credits.items():
print(f"{key} {credit}")
Keep in mind that the range(num) generate numbers from 0 to num-1. So in your code, range(2) only generates 0 and 1.
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)
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
I want to print out all the available keys in the dictionary.
d = {'a': 1, 'c': 1, 'o': 1, 'r': 2, 't': 1}
print(d.keys())
>>> dict_keys(['a', 'c', 'o', 'r', 't'])
but I want to print out all the keys a, c, o, r, r, t ,
because there are 2 r
not only a, c, o, r, t
If you really want to print acorrt :
for key, value in d.items() :
for x in range (0, value):
print(key)
Not sure why you would want to do that, though. As the commenter above mentioned, a key is unique, it's just the value that changes.
a variant using itertools:
from itertools import repeat, chain
d = {'a': 1, 'c': 1, 'o': 1, 'r': 2, 't': 1}
lst = list(chain.from_iterable(repeat(letter, times)
for letter, times in d.items()))
print(lst) # ['r', 'r', 't', 'a', 'c', 'o']
every key (letter) in the dict is repeated as many times as the value (times) suggests; the results are chained together and used in the list constructor.
or without repeat (instead with times * [letter]):
from itertools import chain
lst = list(chain.from_iterable(times * [letter] for letter, times in d.items()))
Thank you, someone posted an answer and I was able to tweek it. It's is for a game and we have to put out all available letters.
for k,v in d.items():
print(k, end = " ")
if v > 1:
print(k, end=" ")
Thank you so much for the help!!! And sharing your knowledge
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.