Trying to write function that returns True if word in list and only made up of letters in hand. I am fine on checking if word in list, but cannot figure out how to iterate through to check the second part. The below is incorrectly returning True:
word = 'chayote'
hand = {'a': 1, 'c': 2, 'u': 2, 't': 2, 'y': 1, 'h': 1, 'z': 1, 'o': 2}
list = ['peach', 'chayote']
def ValidWord(word, hand, list):
if word in list:
for i in word:
if i in hand:
return True
return False
else:
return False
ValidWord(word, hand, list)
The simplest way to solve this would be to use collections.Counter, like this
from collections import Counter
def is_valid_word(word, hand, list):
if word in my_list:
return len(Counter(word) - Counter(hand)) == 0
return False
my_list = ['peach', 'chayote']
hand = {'a': 1, 'c': 2, 'u': 2, 't': 2, 'y': 1, 'h': 1, 'z': 1, 'o': 2}
print is_valid_word("chayote", hand, my_list)
# False
print is_valid_word("peach", hand, my_list)
# False
I think you can use all to do this, might be more concise:
if all(i in hand for i in words):
return True
If the count matters, see #thefourtheye's answer.
You can change the returns inside for loop:
word = 'chayote'
word2 = 'peach'
hand = {'a': 1, 'c': 2, 'u': 2, 't': 2, 'y': 1, 'h': 1, 'z': 1, 'o': 2, 'e': 2} # I added 'e' so chayote is true and peach is false
list = ['peach', 'chayote']
def ValidWord(word, hand, list):
if word in list:
for i in word:
if i not in hand:
return False
return True
else:
return False
print(ValidWord(word, hand, list))
print(ValidWord(word2, hand, list))
If count matters expand Gnijuohz' solution:
def ValidWord(word,hand,list):
return word in list and all(i in hand for i in word) and all(hand[key]>=word.count(key) for key in hand.keys())
This will return False if a letter appears more often in word than the value hand[letter].
If you want to have at least the amount of each letter in the word specified by the hand dictionary, just change it to hand[key]<=word.count(key).
As far as I see the last way would be equivalent to the solution by thefourtheye using Counter
Related
This function takes two character strings corresponding to two words and returns
True if and only if one is anagram of the other, that is, if the words are constituted by the
same letters, ignoring differences between uppercase and lowercase and the order between
characters.
>>> eh_anagrama(’caso’, ’SaCo’)
True
>>> eh_anagrama(’caso’, ’casos’)
False
Simple, but log-linear approach:
def eh_anagrama(s1, s2):
return sorted(s1.lower()) == sorted(s2.lower())
Better linear approach, using collections.Counter:
from collections import Counter
def eh_anagrama(s1, s2):
return Counter(s1.lower()) == Counter(s2.lower())
The benefits of this will probaby only be reaped for very long strings, as the sorting is heavily C-optimized.
How about this with result and char counting in dict.
code
def anagram(s1, s2):
ana = sorted(s1.lower()) == sorted(s2.lower())
d1 = {}
d2 = {}
for x in set(s1): # Get unique char
d1.update({x: s1.count(x)}) # Count each char
for x in set(s2):
d2.update({x: s2.count(x)})
return {'anagram': ana, s1: d1, s2: d2}
s1 = 'caso'
s2 = 'SaCo'
res1 = anagram(s1, s2)
print(res1)
s1 = 'caso'
s2 = 'casos'
res2 = anagram(s1, s2)
print(res2)
Output:
{'anagram': True, 'caso': {'o': 1, 's': 1, 'c': 1, 'a': 1}, 'SaCo': {'o': 1, 'C': 1, 'a': 1, 'S': 1}}
{'anagram': False, 'caso': {'o': 1, 's': 1, 'c': 1, 'a': 1}, 'casos': {'o': 1, 's': 2, 'c': 1, 'a': 1}}
I am trying to write a function which will count the number of characters present in an input string and store as key-value in a dictionary.The code is partially working i.e it is also counting the whitespaces present in between 2 words.How do I avoid counting the whitespaces?
#Store Characters of a string in a Dictionary
def char_dict(string):
char_dic = {}
for i in string:
if i in char_dic:
char_dic[i]+= 1
else:
char_dic[i]= 1
return char_dic
print(char_dict('My name is Rajib'))
You could just continue if the character is a white space:
def char_dict(string):
char_dic = {}
for i in string:
if ' ' == i:
continue
if i in char_dic:
char_dic[i] += 1
else:
char_dic[i]= 1
return char_dic
print(char_dict('My name is Rajib')) # {'j': 1, 'm': 1, 'M': 1, 'i': 2, 'b': 1, 'e': 1, 'a': 2, 'y': 1, 'R': 1, 'n': 1, 's': 1}
A cleaner solution would be:
from collections import defaultdict
def countNonSpaceChars(string):
charDic = defaultdict(lambda: 0)
for char in string:
if char.isspace():
continue
charDic[char] += 1
return dict(charDic)
print(countNonSpaceChars('My name is Rajib')) # {'i': 2, 'a': 2, 'R': 1, 'y': 1, 'M': 1, 'm': 1, 'e': 1, 'n': 1, 'j': 1, 's': 1, 'b': 1}
You can delete space -> string = string.replace (" ","")
def char_dict(string):
char_dic = {}
string=string.replace(" ","")
for i in string:
if i in char_dic:
char_dic[i]+= 1
else:
char_dic[i]= 1
return char_dic
print(char_dict('My name is Rajib'))
To simplify things for you, there's a library called collections that has a Counter function that will produce a dictionary of values and their occurrences in a string. Then, I would simply remove the whitespace key from the dictionary if it is present using the del keyword.
from collections import Counter
def char_dict(string):
text = 'My name is Rajib'
c = Counter(text)
if ' ' in c: del c[' ']
print(char_dict('My name is Rajib'))
This method is very readable and doesn't require too much reinventing.
Write a function named count_letters that takes as a parameter a string and returns a dictionary that tabulates how many of each letter is in that string. The string can contain characters other than letters, but only the letters should be counted. The string could even be the empty string. Lower-case and upper-case versions of a letter should be part of the same count. The keys of the dictionary should be the upper-case letters. If a letter does not appear in the string, then it would not get added to the dictionary. For example, if the string is
"AaBb"
then the dictionary that is returned should contain these key-value pairs:
{'A': 2, 'B': 2}
def count_letters(string):
"""counts all the letters in a given string"""
your_dict = dict()
for x in string:
x = x.upper() # makes lowercase upper
if x not in your_dict:
your_dict[x]= 1
else:
your_dict[x] += 1
return your_dict
I am getting the following error when I go to upload:
Test Failed: {'Q': 1, 'U': 3, 'I': 3, 'S': 6, ' ': 3, 'C[48 chars]': 1} != {'S': 6, 'U': 3, 'I': 3, 'T': 3, 'O': 3, 'C[32 chars]': 1}
+ {'C': 2, 'D': 2, 'E': 2, 'I': 3, 'O': 3, 'P': 1, 'Q': 1, 'S': 6, 'T': 3, 'U': 3}
- {' ': 3,
- '?': 1,
- 'C': 2,
- 'D': 2,
- 'E': 2,
- 'I': 3,
- 'O': 3,
- 'P': 1,
- 'Q': 1,
- 'S': 6,
- 'T': 3,
- 'U': 3}
Try something like this. Feel free to adjust it to your requirements:
import collections
def count_letters(string):
return collections.Counter(string.upper())
print(count_letters('Google'))
Output: Counter({'G': 2, 'O': 2, 'L': 1, 'E': 1})
For documentation of the Counter dict subclass in collections module, check this.
Update without using collections module:
def count_letters(string):
your_dict={}
for i in string.upper():
if i in your_dict:
your_dict[i] += 1
else:
your_dict[i] = 1
return your_dict
Output: {'G': 2, 'O': 2, 'L': 1, 'E': 1}
This solution does use collections, but unlike with Counter we aren’t getting the entire solution from a single library function. I hope it’s permitted, and if it isn’t, that it will at least be informative in some way.
import collections as colls
def count_letters(str_in):
str_folded = str_in.casefold()
counts = colls.defaultdict(int)
for curr_char in str_folded:
counts[curr_char] += 1
return counts
defaultdict is extremely practical. As the name indicates, when we try to index a dictionary with a key that doesn’t exist, it creates a default value for that key and carries out our original operation. In this case, since we declare that our defaultdict will use integers for its keys, the default value is 0.
str.casefold() is a method designed specifically for the complex problem that is case-insensitive comparison. While it is unlikely to make a difference here, it’s a good function to know.
Let me know if you have any questions :)
Without using collections, here is a solution:
def count_letters(string):
string = string.upper()
counts = {}
for a in set(string):
counts[a] = string.count(a)
return counts
This function iterates over set(string), which is equal to all the letters used in your word, without duplicates, and in uppercase. Then it counts how many times each letter appears in your string, and adds it to your counts dictionary.
I hope this answers your question. :)
This question already has answers here:
Counting each letter's frequency in a string
(2 answers)
Closed 4 years ago.
How do I create a function that will let me input a word, and it will execute to create a dictionary that counts individual letters in the code. I would want it to display as a dictionary, for example, by inputting 'hello' it will display {'e': 1, 'h': 1, 'l': 2, 'o': 1}
I AM ALSO required to have 2 arguments in the function, one for the string and one for the dictionary. THIS IS DIFFERENT to the "Counting each letter's frequency in a string" question.
For example, I think I would have to start as,
d = {}
def count(text, d ={}):
count = 0
for l in text:
if l in d:
count +=1
else:
d.append(l)
return count
But this is incorrect? Also Would i need to set a default value to text, by writing text ="" in case the user does not actually enter any word?
Furthermore, if there were existing values already in the dictionary, I want it to add to that existing list. How would this be achieved?
Also if there were already existing words in the dictionary, then how would you add onto that list, e.g. dct = {'e': 1, 'h': 1, 'l': 2, 'o': 1} and now i run in terminal >>> count_letters('hello', dct) the result would be {'e': 2, 'h': 2, 'l': 4, 'o': 2}
If you can use Pandas, you can use value_counts():
import pandas as pd
word = "hello"
letters = [letter for letter in word]
pd.Series(letters).value_counts().to_dict()
Output:
{'e': 1, 'h': 1, 'l': 2, 'o': 1}
Otherwise, use dict and list comprehensions:
letter_ct = {letter:0 for letter in word}
for letter in word:
letter_ct[letter] += 1
letter_ct
You can use pythons defaultdict
from collections import defaultdict
def word_counter(word):
word_dict = defaultdict(int)
for letter in word:
word_dict[letter] += 1
return(word_dict)
print(word_counter('hello'))
Output:
defaultdict(<class 'int'>, {'h': 1, 'e': 1, 'l': 2, 'o': 1})
def count_freqs(string, dictionary={}):
for letter in string:
if letter not in dictionary:
dictionary[letter] = 1
else:
dictionary[letter] += 1
return dictionary
I have started on a program to count vowels and have seemed to be getting nowhere. I need to count vowels from a string and then display the vowels. I need to do this by storing the number of occurrences in variables. Like this :
a = 0
b = 0
....
then print the lowest.
Current code (its not that much ):
string = str(input("please input a string: "))
edit= ''.join(string)
print(edit)
I have tried a number of methods just by my self and don't seem to get anywhere.
You could use a dictionary comprehension:
>>> example = 'this is an example string'
>>> vowel_counts = {c: example.count(c) for c in 'aeoiu'}
>>> vowel_counts
{'i': 2, 'o': 0, 'e': 5, 'u': 0, 'a': 2}
Then finding the minimum, maximum etc. is trivial.
>>> a="hello how are you"
>>> vowel_count = dict.fromkeys('aeiou',0)
>>> vowel_count
{'a': 0, 'i': 0, 'e': 0, 'u': 0, 'o': 0}
>>> for x in 'aeiou':
... vowel_count[x]=a.count(x)
...
>>> vowel_count
{'a': 1, 'i': 0, 'e': 2, 'u': 1, 'o': 3}
now from here you can print low nd max
You can use dictionary for this problem. Iterate over each character and if the character is a vowel, put it in dictionary with count 0 and increment its count by 1, and for every next occurrence keep incrementing the count.
>>> string = str(input("please input a string: "))
please input a string: 'Hello how are you'
>>> dt={} # initialize dictionary
>>> for i in string: # iterate over each character
... if i in ['a','e','i','o','u']: # if vowel
... dt.setdefault(i,0) # at first occurrence set count to 0
... dt[i]+=1 # increment count by 1
...
>>> dt
{'a': 1, 'u': 1, 'e': 2, 'o': 3}
word = input('Enter Your word : ')
vowel = 'aeiou'
vowel_counter = {}
for char in word:
if char in vowel:
vowel_counter[char] = vowel_counter.setdefault(char,0)+1
sorted_result = sorted(vowel_counter.items(), reverse=True,key=lambda x : x[1])
for key,val in sorted_result:
print(key,val)