I'm trying to create a program where if you input a word, it will print out each letter of the word and how many times the letter appears in that word.
Eg; when I input "aaaarggh", the output should be "a 4 r 1 g 2 h 1".
def compressed (word):
count = 0
index = 0
while index < len(word):
letter = word[index]
for letter in word:
index = index + 1
count = count + 1
print(letter, count)
break
print("Enter a word:")
word = input()
compressed(word)
So far it just prints out each letter and position in the word.
Any help appreciated, thank you!
(no using dict method)
Just type (for Python 2.7+):
import collections
dict(collections.Counter('aaaarggh'))
having:
{'a': 4, 'g': 2, 'h': 1, 'r': 1}
a="aaaarggh"
d={}
for char in set(a):
d[char]=a.count(char)
print(d)
output
{'a': 4, 'h': 1, 'r': 1, 'g': 2}
try this, You can use counter it will return dict type
from collections import Counter
print(Counter("aaaarggh"))
One way of implementing it using a dict:
def compressed(word):
letters = dict()
for c in word:
letters[c] = letters.get(c, 0) + 1
for key, value in letters.items():
print(f'{value}{key}', end=' ')
As others have suggested, you can do this easily with a dict !
test_input = "aaaarggh"
def compressed (word):
letter_dict = {}
for letter in test_input:
if letter not in letter_dict:
letter_dict[letter] = 1
else:
letter_dict[letter] = letter_dict[letter]+1
return letter_dict
print(compressed(test_input))
Outputs:
{'a': 4, 'r': 1, 'g': 2, 'h': 1}
Counter is concise. But here's an alternative using defaultdict, which is a subclass of dict.
from collections import defaultdict
test_input = "aaaarggh"
d = defaultdict(int)
for letter in test_input:
d[letter] += 1
https://docs.python.org/3.6/library/collections.html#defaultdict-examples
def counter(word):
dic ={}
for i in [*word]:
counter = word.count(i)
d={i:counter}
dic.update(d)
return dic
counter("aaaarggh")
Related
Implement the function most_popular_character(my_string), which gets the string argument my_string and returns its most frequent letter. In case of a tie, break it by returning the letter of smaller ASCII value.
Note that lowercase and uppercase letters are considered different (e.g., ‘A’ < ‘a’). You may assume my_string consists of English letters only, and is not empty.
Example 1: >>> most_popular_character("HelloWorld") >>> 'l'
Example 2: >>> most_popular_character("gggcccbb") >>> 'c'
Explanation: cee and gee appear three times each (and bee twice), but cee precedes gee lexicographically.
Hints (you may ignore these):
Build a dictionary mapping letters to their frequency;
Find the largest frequency;
Find the smallest letter having that frequency.
def most_popular_character(my_string):
char_count = {} # define dictionary
for c in my_string:
if c in char_count: #if c is in the dictionary:
char_count[c] = 1
else: # if c isn't in the dictionary - create it and put 1
char_count[c] = 1
sorted_chars = sorted(char_count) # sort the dictionary
char_count = char_count.keys() # place the dictionary in a list
max_per = 0
for i in range(len(sorted_chars) - 1):
if sorted_chars[i] >= sorted_chars[i+1]:
max_per = sorted_chars[i]
break
return max_per
my function returns 0 right now, and I think the problem is in the last for loop and if statement - but I can't figure out what the problem is..
If you have any suggestions on how to adjust the code it would be very appreciated!
Your dictionary didn't get off to a good start by you forgetting to add 1 to the character count, instead you are resetting to 1 each time.
Have a look here to get the gist of getting the maximum value from a dict: https://datagy.io/python-get-dictionary-key-with-max-value/
def most_popular_character(my_string):
# NOTE: you might want to convert the entire sting to upper or lower case, first, depending on the use
# e.g. my_string = my_string.lower()
char_count = {} # define dictionary
for c in my_string:
if c in char_count: #if c is in the dictionary:
char_count[c] += 1 # add 1 to it
else: # if c isn't in the dictionary - create it and put 1
char_count[c] = 1
# Never under estimate the power of print in debugging
print(char_count)
# max(char_count.values()) will give the highest value
# But there may be more than 1 item with the highest count, so get them all
max_keys = [key for key, value in char_count.items() if value == max(char_count.values())]
# Choose the lowest by sorting them and pick the first item
low_item = sorted(max_keys)[0]
return low_item, max(char_count.values())
print(most_popular_character("HelloWorld"))
print(most_popular_character("gggcccbb"))
print(most_popular_character("gggHHHAAAAaaaccccbb 12 3"))
Result:
{'H': 1, 'e': 1, 'l': 3, 'o': 2, 'W': 1, 'r': 1, 'd': 1}
('l', 3)
{'g': 3, 'c': 3, 'b': 2}
('c', 3)
{'g': 3, 'H': 3, 'A': 4, 'a': 3, 'c': 4, 'b': 2, ' ': 2, '1': 1, '2': 1, '3': 1}
('A', 4)
So: l and 3, c and 3, A and 4
def most_popular_character(my_string):
history_l = [l for l in my_string] #each letter in string
char_dict = {} #creating dict
for item in history_l: #for each letter in string
char_dict[item] = history_l.count(item)
return [max(char_dict.values()),min(char_dict.values())]
I didn't understand the last part of minimum frequency, so I make this function return a maximum frequency and a minimum frequency as a list!
Use a Counter to count the characters, and use the max function to select the "biggest" character according to your two criteria.
>>> from collections import Counter
>>> def most_popular_character(my_string):
... chars = Counter(my_string)
... return max(chars, key=lambda c: (chars[c], -ord(c)))
...
>>> most_popular_character("HelloWorld")
'l'
>>> most_popular_character("gggcccbb")
'c'
Note that using max is more efficient than sorting the entire dictionary, because it only needs to iterate over the dictionary once and find the single largest item, as opposed to sorting every item relative to every other item.
Hello I asked this question previously and I wanted to adjust the code that I have now. I want to adjust this code so that if a letter is not present in a text string it still returns the value 0 to it assigned.
count = {}
for l in text.lower():
if l in let:
if l in count.keys():
count[l] += 1
else:
count[l] = 1
return count
It currently returns this:
example = "Sample String"
print(func(example, "sao")
{'s': 2, 'a' : 1}
This would be my desired output
example = "Sample String"
print(func(example, "sao"))
{'s': 2, 'a' : 1, 'o' :0}
If you don't mind using tools designed especially for your purpose, then the following will do:
from collections import Counter
def myfunc(inp, vals):
c = Counter(inp)
return {e: c[e] for e in vals}
s = 'Sample String'
print(myfunc(s, 'sao')
Otherwise you can explicitly set all missing values in your functions.
def func(inp, vals):
count = {e:0 for e in vals}
for s in inp:
if s in count:
count[s] += 1
return count
# create a function
def stringFunc(string, letters):
# convert string of letters to a list of letters
letter_list = list(letters)
# dictionary comprehension to count the number of times a letter is in the string
d = {letter: string.lower().count(letter) for letter in letter_list}
return d
stringFunc('Hello World', 'lohdx')
# {'l': 3, 'o': 2, 'h': 1, 'd': 1, 'x': 0}
You can use a Dict Comprehensions and str.count:
def count_letters(text, letters):
lower_text = text.lower()
return {c: lower_text.count(c) for c in letters}
print(count_letters("Sample String", "sao"))
result: {'s': 2, 'a': 1, 'o': 0}
You can use collections.Counter and obtain character counts via the get method:
from collections import Counter
def func(string, chars):
counts = Counter(string.lower())
return {c: counts.get(c, 0) for c in chars}
I'm trying to write a code that does the following:
Takes a number of strings as input
Splits each string into two contiguous substrings of equal length
Returns the minimum number of characters to change to make the two substrings into anagrams of one another (if it's not possible, it must return -1).
Sample Input
6
aaabbb
ab
abc
mnop
xyyx
xaxbbbxx
Sample Output
3
1
-1
2
0
1
For a more detailed explanation about the problem, kindly check this link (no login or sign-up needed).
I've approached the solution pretty well, but it seems like I'm not getting something right, my output is usually a bit greater or smaller than what's expected, and I really don't know what's causing the problem. Here's my code:
n = int(input())
user_input = []
for k in range(n):
user_input.append(input())
results = []
for i in user_input:
if len(list(i))%2 == 0:
left = i[:len(list(i))//2]
right = i[len(list(i))//2:]
left_dict = dict((letter,left.count(letter)) for letter in set(left))
right_dict = dict((letter,right.count(letter)) for letter in set(right))
if left_dict == right_dict:
results.append(0)
else:
shared_items = {k: left_dict[k] for k in left_dict if k in right_dict and left_dict[k] == right_dict[k]}
results.append(len(left) - len(shared_items))
else:
results.append(-1)
print(results)
I appreciate any help in advance.
You started great, with calculating the count for each character in both the substrings, but you never used this power technically.
In this statement:
shared_items = {k: left_dict[k] for k in left_dict if k in right_dict and left_dict[k] == right_dict[k]}
you just calculate items that are in both the dictionary and have same count:
eg. in your 6th testcase:
xaxbbbxx
left_dict will be {'b': 1, 'a': 1, 'x': 2}
right_dict will be {'b': 2, 'x': 2}
and shared_item the way you calculate will give you: {'x':2}
But this doesn't correctly list all the items that are shared.
The correct no. of shared_items should be : {'x':2, 'b':1}
So for that,
What we could then do is calculate the minimum of the item quantities common in the left_dict and right_dict.
i.e. min(left_dict[k],right_dict[k])
the result.append statement will also change accordingly:
else:
shared_items = {k:min(left_dict[k],right_dict[k]) for k in left_dict if k in right_dict}
results.append(len(left)-sum(shared_items.values()))
Full execution:
n = int(input())
user_input = []
for k in range(n):
user_input.append(input())
results = []
for i in user_input:
if len(list(i))%2 == 0:
left = i[:len(list(i))//2]
right = i[len(list(i))//2:]
left_dict = dict((letter,left.count(letter)) for letter in set(left))
right_dict = dict((letter,right.count(letter)) for letter in set(right))
if left_dict == right_dict:
results.append(0)
else:
shared_items = {k:min(left_dict[k],right_dict[k]) for k in left_dict if k in right_dict}
results.append(len(left)-sum(shared_items.values()))
else:
results.append(-1)
print(results)
Input:
6
aaabbb
ab
abc
mnop
xyyx
xaxbbbxx
Output:
[3, 1, -1, 2, 0, 1]
which you could then ofcourse use and print '\n'.join(results) to get the output in the required format.
Two words are anagrams if the same letters appear with the same occurrencies.
from collections import Counter
sl = ["aaabbb", "ab", "abc", "mnop", "xyyx", "xaxbbbxx"]
def f(s):
if len(s)%2 != 0:
return -1
a = s[:len(s)//2]
b = s[len(s)//2:]
print(Counter(b) - Counter(a))
return sum( (Counter(b) - Counter(a)).values() )
list(map(f, sl))
Counter({'b': 3})
Counter({'b': 1})
Counter({'o': 1, 'p': 1})
Counter()
Counter({'b': 1})
[3, 1, -1, 2, 0, 1]
I have a String like this str = "aabcccdfffeeeeettaaaattiioccc"
I need output like this Result ={aa: 1;b:1;ccc:2;d:1;fff:1;eeeee:1;tt:2;aaaa:1;ii:1;o:1;ccc:1}
I have tried it like this so far:
def repeating_letters(the_string):
temp = []
count = 0
for i in range(len(the_string)):
if(the_string[i] == the_string[i]):
if(the_string[i] == the_string[i+1]):
temp = the_string[i]
# count = count+1
print(the_string[i])
if name__== "__main":
the_string = "aaafassskfahfioejwwa"
repeating_letters(the_string)
Hints
I would follow this steps:
Create a list where I will store my partial strings
Start iterating the string
Store the initial position and the current character
Keep iterating until the character is different
Store in the list the partial string from the initial position you stored until 1 less than the current position
Update the initial position to the current one and the current character
Use the list to create a collections.Counter
About your code, the_string[i] == the_string[i] will always be true.
SPOILER: solution
from collections import Counter
def repeating_letters(the_string):
partials = []
initial = 0
for i, character in enumerate(the_string):
if character == the_string[initial]:
continue
partials.append(the_string[initial:i])
initial = i
partials.append(the_string[initial:]) # Needed for the last partial string
return Counter(partials)
As #prahantrana mentions in a comment, getting the partials can be done in a one-liner with the groupby method from the itertools library.
from collections import Counter
from itertools import groupby
def repeating_letters(the_string):
return Counter(''.join(group) for _, group in groupby(the_string))
Or
from collections import Counter
from itertools import groupby
def repeating_letters(the_string):
return Counter(char*len(list(group)) for char, group in groupby(the_string))
I'm not sure which of them is faster.
from collections import Counter
from itertools import groupby
def splitter(text):
"""
text: str
return : frequency of continous characters
"""
string = [''.join(group) for key, group in groupby(text)]
return Counter(string)
l = 'aaaabcccdfffeeeeettfffaaaattiioccceeeeeeaaaa'
print(splitter(l))
output
Counter({'aaaa': 3, 'ccc': 2, 'fff': 2, 'tt': 2, 'b': 1, 'd': 1, 'eeeee': 1, 'ii': 1, 'o': 1, 'eeeeee': 1})
other way , coded method, not using any library
from collections import Counter
def function(string):
"""
string: str
return: frequency of continous same character
"""
res = []
tmp = []
if len(string)==0:
return Counter('')
val = string[0]
for i in range(1, len(string)):
if string[i] == val:
tmp.append(val)
val =string[i]
else:
tmp.append(val)
res.append(tmp)
tmp = []
val = string[i]
tmp.append(val)
res.append(tmp)
p = [''.join(i) for i in res]
return Counter(p)
l ='aaaabcccdfffeeeeettfffaaaattiioccceeeeeeaaaa'
print(function(l))
output
Counter({'aaaa': 3, 'ccc': 2, 'fff': 2, 'tt': 2, 'b': 1, 'd': 1, 'eeeee': 1, 'ii': 1, 'o': 1, 'eeeeee': 1})
In my experiences, this is a special work to do. I searched in many different ways but still can't find answer to it.
here the question is.
I have a dict of Chinese phrase frequency.It looks like:
{'中国':18950, '我们':16734, '我国':15400, ...}
What I need to do is count every single character's frequency, for example:
character '国' appears in two phrases ('中国'and '我国') , so this character's frequency should be:
{'国':(18950+15400)}
How can I achieve this?
Simple example,
d = {'abd':2, 'afd':3}
f = {}
for key in d:
strlen = len(key)
for i in range(strlen):
if key[i] in f:
f[key[i]] += d[key]
else:
f[key[i]] = d[key]
print f #gives {'a': 5, 'b': 2, 'd': 5, 'f': 3}
My way:
from collections import Counter
c={'中国':18950, '我们':16734, '我国':15400}
print(Counter([j for k,v in c.items() for i in k for j in [i]*v]))
Output:
Counter({'国': 34350, '我': 32134, '中': 18950, '们': 16734})
Something like this should work:
from collections import defaultdict
char_dict = defaultdict(int)
for phrase, count in phrase_dict.iteritems():
for char in phrase:
char_dict[char] += count
d = {'中国':18950, '我们':16734, '我国':15400, ...}
q = 0
for i in d:
if '国' in i:
a = (d[i])
q += a
print(q)